After reading the posts from badidea and coderJeff I thought I might post my first attempt. I thought maybe I could replace the graphics with quickly drawn PAINT images to replace the original sprite images. They don't look as good. It is amazing what good graphics can do to enhance a game's appearance although game play is a separate issue.
Download this image and resave as spriteBlock.bmp
The few tiles used are are generated in the program code.
Arrow keys left/right. Jump with Up arrow key. Control key punches arm. Punch botton on right wall will exit program. Punch enemy to stop it. The yellow floor tile was a take on Wonder boys trampoline tile.
Code: Select all
screenres 640,480,32
color rgb(0,0,0),rgb(255,255,255)
cls
'GLOBAL VARIABLES
dim shared as integer GameOver 'flag a game end event has occurred
dim shared as integer hitGround,hitRoof,hitRightWall,hitLeftWall
dim shared as integer mx,my,mb 'mouse variables
dim shared as double now1
now1 = timer
dim shared as integer jumpCounter 'count how long up key pressed
dim shared as integer state 'state of hero
dim shared as integer WINW,WINH,WINX,WINY 'DISPLAY window of bitmap
WINX = 0
WINY = 0
WINW = 640
WINH = 380
const MAPW = 60 ' size in tiles
const MAPH = 20 '
const TILEW = 32 ' size in pixels
const TILEH = 32
dim shared as integer BMAPW = MAPW*TILEW
dim shared as integer BMAPH = MAPH*TILEH
dim shared as any ptr LAYER0 'background
LAYER0 = imagecreate(BMAPW,BMAPH)
dim shared as any ptr LAYER1 'areas behind sprites
LAYER1 = imagecreate(BMAPW,BMAPH)
dim shared as any ptr LAYER2 'areas that contact sprites
LAYER2 = imagecreate(BMAPW,BMAPH)
dim shared as any ptr LAYER3 'areas in front of sprites
LAYER3 = imagecreate(BMAPW,BMAPH)
dim shared as any ptr DISPLAY
DISPLAY = imagecreate(BMAPW,BMAPH) 'holds combination of layers for display
dim shared as integer tileID(MAPW,MAPH) 'holds tile ID's
'========= LOAD TILE BLOCK BITMAP =========
dim as any ptr tileBlock
tileBlock = imagecreate(TILEW*16,TILEH*16,rgb(255,0,255))
'bload "tileBlock.bmp",tileBlock
'== create tiles used ===
line tileBlock,(32,0)-step(31,31),rgb(200,100,200),bf 'background tiles
line tileBlock,(32,0)-step(31,31),rgb(0,0,0),b
line tileBlock,(256,0)-step(31,31),rgb(100,100,20),bf 'tile with button
line tileBlock,(256,0)-step(31,31),rgb(0,0,0),b
circle tileBlock,(272,16),10,rgb(195,195,195),,,,f 'draw gray button
line tileBlock,(0,128)-step(31,31),rgb(0,162,232),bf 'sky
line tileBlock,(32,128)-step(31,31),rgb(0,128,0),bf 'wall tiles
line tileBlock,(32,128)-step(31,31),rgb(0,0,0),b
line tileBlock,(32,160)-step(31,31),rgb(200,200,0),bf
line tileBLock,(32,160)-step(31,31),rgb(0,0,0),b 'trampoline tile
'========= LOAD BITMAP BLOCK OF SPRITES ====
dim shared as any ptr spriteBlock
spriteBlock = imagecreate(300,182)
bload "spriteBlock.bmp",spriteBlock
'read tile data
dim as integer xx,yy,ID
for i as integer = 0 to MAPW-1
for j as integer = 0 to MAPH-1
read tileID(i,j)
ID = tileID(i,j)
'get xx,yy coordinate of tile ID in spriteBlock
yy = int(ID/16)
xx = ID - (yy*16)
'copy tile image into layer
if ID>64 then
put LAYER2,(i*TILEW,j*TILEH),tileBlock,(xx*TILEW,yy*TILEH)-(xx*TILEW+TILEW-1,yy*TILEH+TILEH-1),pset
else
put LAYER1,(i*TILEW,j*TILEH),tileBlock,(xx*TILEW,yy*TILEH)-(xx*TILEW+TILEW-1,yy*TILEH+TILEH-1),pset
end if
next j
next i
' ================== create a sprite ========
type SPRITE
as integer x
as integer y
as integer w
as integer h
as double dx 'left = -dx, right = +dx not moving = 0
as double dy 'up/down
as integer f 'frame number for animated sprites images
as integer c 'timer counter for animation
as integer d 'last direction along x axis
as integer alive 'alive?
end type
'create sprite
dim shared as SPRITE hero
dim shared as SPRITE mole
dim shared as integer heroHitMole
' ----------- initialize sprite data --------------
hero.w = 47
hero.h = 59
hero.x = 500
hero.y = 609-hero.h
hero.dx = 0
hero.dy = 4 'gravity
hero.alive = 1
mole.w = 32
mole.h = 32
mole.x = 140
mole.y = 609-mole.h
mole.dx = 1
mole.dy = 0
mole.alive = 1
'---------------------------------------------------
function testCollision(b1 as SPRITE,b2 as SPRITE) as boolean
return b2.y < (b1.y + b1.h) and (b2.y + b2.h) > b1.y and b2.x < (b1.x + b1.w) and (b2.x + b2.w) > b1.x
end function
function spriteCollision(s1 as SPRITE,s2 as SPRITE) as integer
dim as integer hit
hit = 0
'top/left corner
if s1.x >= s2.x and s1.x <= (s2.x+s2.w) then
if s1.y >= s2.y and s1.y <= (s2.y+s2.h) then
hit = hit or 1
end if
end if
'top/right corner
if s1.x+s1.w >= s2.x and s1.x+s1.w <= (s2.x+s2.w) then
if s1.y >= s2.y and s1.y <= (s2.y+s2.h) then
hit = hit or 2
end if
end if
'bottom/left corner
if s1.x >= s2.x and s1.x <= (s2.x+s2.w) then
if s1.y+s1.h >= s2.y and s1.y+s1.h <= (s2.y+s2.h) then
hit = hit or 4
end if
end if
'bottom/right corner
if s1.x+s1.w >= s2.x and s1.x+s1.w <= (s2.x+s2.w) then
if s1.y+s1.h >= s2.y and s1.y+s1.h <= (s2.y+s2.h) then
hit = hit or 8
end if
end if
return hit
end function
sub updateData()
if hitGround = 1 then
jumpCounter = 0
else
'air friction
if hero.dx > 0 then
hero.dx = hero.dx - .1
end if
if hero.dx < 0 then
hero.dx = hero.dx + .1
end if
end if
'==========
' if hitGround = 1 then
hero.dx = 0 'can only move when on ground and left/right key down
'MOVE RIGHT
if multikey(&H4D) then
hero.dx = 4
hero.d = 1
end if
'MOVE LEFT
if multikey(&H4B) then
hero.dx = -4
hero.d = -1
end if
' end if
'JUMP UP
if multikey(&H48) then
if hitGround = 1 then
hitGround = 0
hero.dy = -8 'updward velocity
jumpCounter = 12 'start time in air counter
else 'in the air
if jumpCounter > 0 then
jumpCounter = jumpCounter - 1
hero.dy = -8
end if
end if
end if
if hero.f > 3 then hero.f = 0
if multikey(&H1D) then 'control key
hero.f = 4 'draw sword sprite
end if
' CHARACTER DUCKS DOWN OR JUMPS DOWN THROUGH PLATFORM
' if multikey(&H1F) or multikey(&H50) then
' end if
'update position and test for out of bounds
hero.x = hero.x + hero.dx
if hero.x < 0 then hero.x = 0
if hero.x > BMAPW-hero.w then
hero.x = bMAPW-hero.w
end if
hero.y = hero.y + hero.dy 'moves down
if hero.dy < 4 then
hero.dy = 4 'constant velocity no acceleration or friction
end if
if hero.y < 0 then hero.y = 0
if hero.y > BMAPH-hero.h then
hero.y = bMAPH-hero.h
end if
if hero.y<0 then hero.y = 0
if hero.y>BMAPH-hero.h then
hero.y = BMAPH-hero.h
end if
'scroll screen if required
WINX = hero.x - (WINW\2)
if WINX < 0 then WINX = 0
if WINX > (BMAPW - WINW) then WINX = (BMAPW - WINW)
WINY = hero.y - (WINH\2)
if WINY < 0 then WINY = 0
if WINY > (BMAPH - WINH) then WINY = (BMAPH - WINH)
'update sprite frame
if hero.dx <> 0 then 'must be running
if hero.c < 5 then
hero.c = hero.c + 1
else
hero.c = 0
hero.f = hero.f + 1
if hero.f > 3 then
hero.f = 0
end if
end if
end if
'test for sprite collision
if mole.alive = 1 then
if spriteCollision(mole,hero)<>0 then
if hero.f = 4 then 'hero striking out
mole.alive = 0
mole.f = 2 'dead mole
else
hero.f = 5 'struck hero
'toss hero
end if
end if
end if
if mole.alive = 1 then
'update frame
mole.c = mole.c + 1
if mole.c = 25 then
mole.c = 0
mole.f = mole.f + 1
if mole.f > 1 then
mole.f = 0
end if
end if
'reverse direction if hit wall
mole.x = mole.x + mole.dx
if mole.x<32 or mole.x >= BMAPW - 64 then
mole.dx = -mole.dx
end if
end if
'=====================
dim as integer px1,px2
px1 = hero.w\3:px2 = px1*2 'two between top and bottom
hitRoof = 0
hitGround = 0
'test for contact with roof
if point(hero.x+px1,hero.y,LAYER2)<>rgb(255,0,255) or point(hero.x+px2,hero.y,LAYER2)<>rgb(255,0,255) then
hitRoof = 1
'move down until no longer hits roof
while point(hero.x+px1,hero.y,LAYER2)<>rgb(255,0,255) or point(hero.x+px2,hero.y,LAYER2)<>rgb(255,0,255)
hero.y = hero.y + 1
wend
'GET TILE NUMBER
end if
'test for contact with ground
if point(hero.x+px1,hero.y+hero.h-1,LAYER2)<>rgb(255,0,255) or point(hero.x+px2,hero.y+hero.h-1,LAYER2)<>rgb(255,0,255) then
hitGround = 1
'move up until no longer hits ground
while point(hero.x+px1,hero.y+hero.h-1,LAYER2)<>rgb(255,0,255) or point(hero.x+px2,hero.y+hero.h-1,LAYER2)<>rgb(255,0,255)
hero.y = hero.y - 1
wend
'GET TILE NUMBER
end if
dim as integer py1,py2
py1 = hero.h\3:py2 = py1*2 'two between top and bottom
'test for contact with right wall
if point(hero.x+hero.w-1,hero.y+py1,LAYER2)<>rgb(255,0,255) or point(hero.x+hero.w-1,hero.y+py2,LAYER2)<>rgb(255,0,255) then
hitRightWall = 1
'move left until no longer hits right wall
while point(hero.x+hero.w-1,hero.y+py1,LAYER2)<>rgb(255,0,255) or point(hero.x+hero.w-1,hero.y+py2,LAYER2)<>rgb(255,0,255)
hero.x = hero.x - 1
wend
'GET TILE NUMBER
end if
'test for contact with left wall
if point(hero.x,hero.y+py1,LAYER2)<>rgb(255,0,255) or point(hero.x,hero.y+py2,LAYER2)<>rgb(255,0,255) then
hitLeftWall = 1
'move right until no longer hits left wall
while point(hero.x,hero.y+py1,LAYER2)<>rgb(255,0,255) or point(hero.x,hero.y+py2,LAYER2)<>rgb(255,0,255)
hero.x = hero.x + 1
wend
'GET TILE NUMBER
end if
'on trampoline
if tileID(hero.x\tileW+0,hero.y\tileH+2)=81 or tileID(hero.x\tileW+1,hero.y\tileH+2)=81 then
if hitGround = 1 then
hitGround = 0
hero.dy = -88 'updward velocity
jumpCounter = 212 'start time in air counter
end if
end if
end sub
sub updateDisplay()
'put DISPLAY,(0,0),LAYER0,pset 'sky and clouds
put DISPLAY,(0,0),LAYER1,trans 'areas behind sprites
put DISPLAY,(0,0),LAYER2,trans 'areas that interact with sprite
'put DISPLAY,(0,0),LAYER3,trans 'areas in front of sprite
'draw mole sprite
if mole.f < 2 then
if mole.dx = 1 then 'moving left or right
put DISPLAY,(mole.x,mole.y),spriteBlock,(mole.f*mole.w,150)-(mole.f*mole.w+mole.w-1,150+31),trans
else
put DISPLAY,(mole.x,mole.y),spriteBlock,(mole.f*mole.w,119)-(mole.f*mole.w+mole.w-1,119+31),trans
end if
end if
if mole.f = 2 then
put DISPLAY,(mole.x,mole.y),spriteBlock,(64,119)-(64+31,119+31),trans
end if
'draw character sprite
if hero.f < 4 then
if hero.d = 1 then 'moving left or right
put DISPLAY,(hero.x,hero.y),spriteBlock,(hero.f*hero.w,59)-(hero.f*hero.w+hero.w-1,59+58),trans
else
put DISPLAY,(hero.x,hero.y),spriteBlock,(hero.f*hero.w,0)-(hero.f*hero.w+hero.w-1,57),trans
end if
end if
if hero.f = 4 then 'hero striking out
if hero.d = 1 then 'moving left or right
put DISPLAY,(hero.x,hero.y),spriteBlock,(188,0)-(188+63,57),trans
else
put DISPLAY,(hero.x-14,hero.y),spriteBlock,(188,59)-(188+63,59+58),trans
end if
end if
if hero.f = 5 then 'hit by enemy
put DISPLAY,(hero.x,hero.y),spriteBlock,(254,0)-(254+47,59),trans
end if
put DISPLAY,(0,0),LAYER3,trans 'areas in front of sprites
'show visible part of DISPLAY image
screenlock()
put (0,0),DISPLAY,(WINX,WINY)-(WINX+WINW-1,WINY+WINH-1),pset 'show visible part
locate 2,2
print tileID(hero.x\tileW+2,hero.y\tileH);" ";
print tileID(hero.x\tileW+2,hero.y\tileH+1)
'did hero press tile with exit key?
if hero.f = 4 and tileID(hero.x\tileW+2,hero.y\tileH)=8 then
gameOver = 1
end if
screenunlock()
end sub
updateDisplay()
do
if timer > now1 + 0.00001 then
now1 = timer
updateData()
updateDisplay()
end if
sleep 2
loop until multikey(&H01) or gameOver = 1 'esc key or hero enters castle
imagedestroy(DISPLAY)
imagedestroy(LAYER3)
imagedestroy(LAYER2)
imagedestroy(LAYER1)
imagedestroy(LAYER0)
'tile array
DATA 64,64,64,64,64,64,64,64,65,65,65,65,65,65,65,65,65,8,65,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,81
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,1,1,1,1,65
DATA 64,64,64,64,64,64,64,64,65,65,65,65,65,65,65,65,65,8,65,65