Simple Game framework

Game development specific discussions.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

leopardpm wrote:How about this idea... perhaps this would be a good, simple, game to collaborate on - perhaps start with the good code you already have, divide up the remaining routines that need done (the list in last post is maybe a good start), and in completing the game it would also perhaps help both of us understand something that I am totally unfamiliar with - programming with multiple coders... I never have used things like GitHub and such, but I feel like it could be invaluable in bigger projects with multiple people coding on the same project... not saying that we would use GitHub, but if you know how to use it then I would love to learn!

.. or, could just finish the game off individually - it is simple enough, yet still would provide challenges as I haven't ever 'completed' a finished game, even a simple one like this - so there would be things learned from doing so.
Do you still have the email address I used to send images for the isometric project? Unfortunately I seem to have deleted all your replies so haven't got the email address you provided.

Firstly I would hate for it to be a pengo clone. That is ok to hone your coding skills and keeping the result to yourself but we may as well make it original even if it incorporates ideas from other similar games like pengo.

For a moving block I would suggest that when a block tile is pushed just delete the block tile and replace it with a block sprite with a velocity in the direction of the push. When the block sprite hits a tile it turns back into a block tile.

When I started to implement the block pushing suggestion I realized it was going to become messy and hard to read and potentially full of bugs so I have gone back and recoded the whole program. Although I like the coding and it looks correct it doesn't detect sprite to sprite collisions anymore but it is too late at night now so I will tackle it tomorrow, I tend to be a morning person :)

As for images in data statements I have already used characters.

http://www.freebasic.net/forum/viewtopi ... 15&t=21667

Using decimal numbers was mainly for small images with many colors that result from shading and dithering of the image. However if you limit the images to say 32 colors you could code them as strings of characters or code two colors in a character if you limit the palette to 16 colors. An image can be processed to reduce the color range.
.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

For a moving block I would suggest that when a block tile is pushed just delete the block tile and replace it with a block sprite with a velocity in the direction of the push. When the block sprite hits a tile it turns back into a block tile.
I am thinking that doing it that way will complicate things... what about have all blocks just start out as sprites, no real 'map', that way they are 'ready to go' when pushed.... no adjust map or initializing a 'new' item to be animated(sliding)? This would also make them easy to have a 'standing still' animation for special blocks. Just a thought...
Do you still have the email address I used to send images for the isometric project? Unfortunately I seem to have deleted all your replies so haven't got the email address you provided.
you deleted me? so sad... guess I made ya mad somehow... lol... yes, same email address

I will dredge up an email from you and send you an email as well (i never delete stuff, its free to keep it around!)
Firstly I would hate for it to be a pengo clone. That is ok to hone your coding skills and keeping the result to yourself but we may as well make it original even if it incorporates ideas from other similar games like pengo.
I was thinking, if we are going to do this, that we could get the 'basic' pengo working, with sliding blocks and squishing things, then we could start altering gameplay - like incorporating special enemies that might be able to go through walls occassionally, or special blocks that explode or whatever... maybe power ups that speed up pengo (or enemies), maybe make it a mash up of pengo and pac-man... anything is fine... my creativity at this late of night is very limited...

I like how your pengo sprite seems to 'ice skate' in his animation, don't know if you did that on purpose or not.
As for images in data statements I have already used characters.
yup, I see.... but there are so many limitations: number of colors used & especially number of animation frames and overall size of images (forum limits to 60,000 characters per post). with what I have almost completed, the image will be an indexed RGBA(32 bit), 256 colors per image, 4096x4096 pixel size max. And it will be compressed RLE so it can fit most all of what we would send to each other via forum into a single post instead of multiple posts to cut/paste together. Just thought it would be handy... I like figuring out data compression schemes (but don't know alot except for RLE) so this 'project' got my interest for the evening....
Last edited by leopardpm on Mar 04, 2017 20:17, edited 1 time in total.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

<deleted>
Last edited by leopardpm on Mar 04, 2017 20:19, edited 1 time in total.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

An image can be processed to reduce the color range.
hate the thought of the forums limitations restricting or otherwise negatively altering your awesome artistic images in their original form!
jcfuller
Posts: 325
Joined: Sep 03, 2007 18:40

Re: Simple Game framework

Post by jcfuller »

Just lurking here.
Why not start a github repository along with github pages for your project?
https://github.com/
https://pages.github.com/

You don't need to treat it as a traditional git repository. I wanted a place where I could have html pages I could link to from forum messages without filling up my personal web site or subscribing to one of the free services that are only up when they feel like it.
This is my github link
https://github.com/jcfuller/bc9Basic
and this is a direct link to an html page
http://jcfuller.github.io/bc9Basic/CW_CC_Button.html

James
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

what? sounds perfect

never used GitHub, kinda browsed it though... will try and figure it out.... THANKS! didnt know images could be stored and shared there...
Last edited by leopardpm on Mar 04, 2017 13:42, edited 1 time in total.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

could you put an store an example BMP image there and link to it from a forum post so I can see how it would work?
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

BC, when you get a chance, click this link to see if you can access the GitHub repository I made with a BMP, a BMPX, and a BAS file to test...
this could make it MUCH easier to transfer images as well as learn about the collaborative features and maintaining a project between multiple folks... i don't yet fully understand the whole branching and forks and such... but, it makes sense.

I am trying to see if it somehow will automatically 'synch' with a designated local folder, or if you (and I) need to 'download' each time to make changes etc... so far my understanding is that one needs to download the latest code, or any 'branch' (a version of the master(committed) code, which you might make changes to) - and I don't know how to add you as a collaborator, looks like you need to 'sign up' in order to be one - is easy/free... but requires an email address....

https://github.com/leopardpm/FBengo

have you used GitHub before?

test to see if forum will display a github hosted image:
Image
looks like... no

now test just a link directly to image:
https://github.com/leopardpm/FBengo/blo ... nguin1.bmp

another image attempt:
Image

nope.... last attempt: WORKS!
Image
looks like to show github images in a forum post, you go to that image in github, then 'View Raw' - it will display the image in your browser - then copy the address in the address bar and paste it into the post between the IMG declarations.... easy enough!

Image
Image
ok, the above two tests were to see how to do it with a transparent PNG image.... basically the same except there is no clicking on 'View Raw' as the image just shows up - when it show, then right click and "copy image address", paste that into post... is a bit easier.... doesn't work with BMPX files though...

ok enough for me... going to sleep now
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

@Leopardpm,

You can go back and delete your email address from the previous post now.

My "awesome" artistic images only have a few colors anyway as I haven't added any color smoothing or blended colors as I see have been used in the actual Pengo game character on utube. I consider probably 16 colors is sufficient for demo images to the forum. Yes there is a lot of redundancy in these images so they could be reduced in size and coded as character strings. Fancy images could be added later should an original game ever be completed.

We need to come up with original characters and by all means having pushing tiles and other ideas from other games but an exact clone of Pengo I am not keen on for ethical and copy write reasons.

As for collaboration I see that happening anyway with an exchange of ideas, suggestions and code analysis.

Never used GitHub and at this stage I am easy with just using this forum.

The ice skating is probably due to the animations having insufficient frames for the velocity of the character. In one of my other demos I made sure the feet touched the ground exactly without sliding.
http://www.freebasic.net/forum/viewtopi ... 15&t=22633

The thing about tiles is they don't move, have fixed exact spaced positions which are required by the sprite/tile collision detection I am using and don't have to be checked for collisions with each other. They can be animated and have other properties but their data is all in one simple array which can be displayed by two simple for/next loops.

The method of replacing a tile with a sprite, to then be processed as a sprite when it is moved with pixel precision (rather than jumping tile positions), works well. I first used it to move chess pieces when they were selected and moved with the mouse.

Now to find this sprite collision bug before I post my latest offering.
.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

This is my more modular version which I think will be easier to work with and modify than the first one.

Code: Select all

const WORLDW = 13
const WORLDH = 15

type AGENT
    as integer x         'current position
    as integer y
    as integer w
    as integer h
    as integer dx        'velocity between -1 and +1
    as integer dy
    as integer d         'direction
    as integer f         'current frame
    as integer tf        'total frames
    as integer count     'delay between frame increment
    as integer ID
    as any ptr img       'sprite image block
end type

dim shared as integer count  'frame delay

dim shared as integer agentCount
agentCount = 5

const TILEW = 32
const TILEH = 32

const SCRW = WORLDW*TILEW
const SCRH = WORLDH*TILEH

dim shared as integer WINX,WINY,WINW,WINH

screenres SCRW, SCRH, 32
color rgb(0,0,0),rgb(255,255,255):cls
dim shared as any ptr greenBlob
greenBlob = imagecreate(96,128)
bload "greenBlob1.bmp",greenBlob

dim shared as any ptr redPenguin
redPenguin = imagecreate(96,128)
bload "redPenguin1.bmp",redPenguin

dim shared as AGENT ag(0 to agentCount-1)

for i as integer = 1 to agentCount-1  'skip player ag(0) and player(agentCount-1)
    ag(i).w = 32
    ag(i).h = 32
    ag(i).y = 0
    ag(i).x = i*TILEW*2
    ag(i).id = i
    ag(i).dx = int(rnd(1)*3)-1
    ag(i).dy = int(rnd(1)*3)-1
    while ag(i).dx = 0 and ag(i).dy=0
        ag(i).dx = int(rnd(1)*3)-1
        ag(i).dy = int(rnd(1)*3)-1
    wend
    ag(i).img = greenBlob
next i

ag(0).id = 0
ag(0).w = 32
ag(0).h = 32
ag(0).img = redPenguin


dim shared as integer world(WORLDW,WORLDH)
for j as integer = 0 to WORLDH-1
    for i as integer = 0 to WORLDW-1
        read world(i,j)
    next i
next j

function spriteCollision(b1 as AGENT,b2 as AGENT) 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

sub drawWorld()
    screenlock
    cls
    'draw tiles
    for j as integer = 0 to  WORLDH-1
        for i as integer = 0 to WORLDW-1
            if world(i,j)=1 then
                line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(100,100,200),bf
            end if
            if world(i,j)=2 then
                line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(200,100,100),bf
            end if
        next i
    next j
   
    'draw agents
    for i as integer = 0 to agentCount-1
        if ag(i).dx = 0 and ag(i).dy = 0 then ag(i).f = 1
        draw string (ag(i).x,ag(i).y),str(i)
        put (ag(i).x,ag(i).y),ag(i).img,(ag(i).f*32,ag(i).d*32)-(ag(i).f*32+31,ag(i).d*32+31),trans
    next i
    
    
    screenunlock
    
end sub

sub makeMove(ag as AGENT)
    ag.x = ag.x + ag.dx
    ag.y = ag.y + ag.dy
end sub
    
function outOfBounds(ag as AGENT) as boolean
    if ag.x < 0 or ag.x > SCRW-TILEW or ag.y < 0 or ag.y > SCRH-TILEH then
        return TRUE
    else
        return FALSE
    end if
end function

function tileCollision(ag as AGENT) as boolean
    dim as boolean hit
    dim as integer TILEX,TILEY
    'test overlap of another tile
    TILEX = int(ag.x/TILEW)
    TILEY = int(ag.y/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1
    
    return hit
    
end function
       
sub undoMove(ag as AGENT)
    ag.x = ag.x - ag.dx 'undo move
    ag.y = ag.y - ag.dy
end sub
    
sub changeDirection(ag as AGENT)
    ag.dx = int(rnd(1)*3)-1
    ag.dy = int(rnd(1)*3)-1
    while (ag.dx and ag.dy) or (ag.dx=0 and ag.dy=0)
        ag.dx = int(rnd(1)*3)-1
        ag.dy = int(rnd(1)*3)-1 
    wend
end sub
    
function onTile(ag as AGENT) as boolean
    if ag.x = int(ag.x\TILEW)*TILEW and ag.y = int(ag.y\TILEH)*TILEH then
        return TRUE
    else
        return FALSE
    end if
end function

sub setDirection(ag as AGENT)
    If ag.dx < 0 then ag.d = 1
    If ag.dx > 0 then ag.d = 2
    If ag.dy < 0 then ag.d = 3
    If ag.dy > 0 then ag.d = 0 
end sub

sub upDateFrame(ag as AGENT)
    ag.count = ag.count + 1
    if ag.count>10 then
        ag.count = 0
        ag.f = ag.f + 1
        if ag.f = 3 then ag.f = 0
    end if
end sub

sub update()
    dim as integer hit
    
    for i as integer = 0 to agentCount-1
        
        hit = 0
        
        makeMove(ag(i))
        
        if outOfBounds(ag(i)) then
            hit = 1
        end if
        
        if tileCollision(ag(i)) then
            hit = 1
        end if
        
        updateFrame(ag(i))
        
        for j as integer = 0 to agentCount-1 'for each other sprite
            if i <> j then  'not with itself
                if spriteCollision(ag(i),ag(j)) = TRUE then
                    hit = 1
                end if
            end if
        next j
        
        if hit = 1 then
            undoMove(ag(i))
            changeDirection(ag(i))
            setDirection(ag(i))
        end if
        
    next i
    
    'read player input if on center of tile
    if onTile(ag(0)) then
        ag(0).dx = 0
        ag(0).dy = 0
        'only one of four directions possible
        If MultiKey(&H4B) then ag(0).dx = -2:ag(0).dy = 0
        If MultiKey(&H4D) then ag(0).dx =  2:ag(0).dy = 0
        If MultiKey(&H48) then ag(0).dy = -2:ag(0).dx = 0
        If MultiKey(&H50) then ag(0).dy =  2:ag(0).dx = 0
        setDirection(ag(0))
    end if
    
    
end sub



dim as double now1
now1 = timer

update()

do
   
    if timer > now1 + 0.01 then
        now1 = timer
        update()
        drawWorld()
    end if
   
    sleep 2

loop until multikey(&H01)

data 0,1,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,1,1,1,1,1,1,0,0,1,0
data 0,1,0,1,0,1,0,1,0,1,0,0,0
data 1,2,0,2,0,0,0,0,0,1,0,2,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 0,0,1,0,0,0,1,1,0,1,0,1,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 1,1,1,0,1,1,0,1,1,1,0,1,0
data 0,0,0,0,0,0,0,1,0,1,0,0,0
data 0,0,0,0,1,1,0,0,0,0,0,1,1
data 0,0,0,0,0,1,0,0,0,0,0,0,0
data 0,1,0,0,0,1,0,1,0,0,0,0,0
data 0,1,0,0,0,0,0,0,1,1,0,1,0
data 0,0,0,0,0,0,0,0,0,0,0,1,0
data 0,1,0,0,0,0,0,0,0,1,0,1,0
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

leopardpm wrote:Quick question, BC - Do you hand draw each frame of these penguins, then copy/paste them into one spritesheet? or do you use a sprite making program which allows you to see the animation as you draw and makes the spritesheet for you?
I was just using your penguin sprite for testing purposes and the question occurred to me...
I created everything using MS PAINT.
.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Simple Game framework

Post by D.J.Peters »

Hello BasicCoder2 I made ~16 but short changes all changes marked by ' !!!

Joshy

Code: Select all

' !!! first const's (they are global also)
const WORLDW = 13
const WORLDH = 15

const TILEW = 32
const TILEH = 32

const SCRW = WORLDW*TILEW
const SCRH = WORLDH*TILEH

' !!! second types
type AGENT
  as integer x         'current position
  as integer y
  as integer w
  as integer h
  as integer dx        'velocity between -1 and +1
  as integer dy
  as integer d         'direction
  as integer f         'current frame
  as integer tf        'total frames
  as integer count     'delay between frame increment
  as integer ID
  as any ptr img       'sprite image block
end type

' !!! third globals
dim shared as integer count  'frame delay
dim shared as integer agentCount
dim shared as integer WINX,WINY,WINW,WINH
dim shared as any ptr greenBlob
dim shared as any ptr redPenguin

agentCount = 5

screenres SCRW, SCRH, 32, 2 ' !!! a hidden drawing page with flip are faster then screenlock screenunlock
screenset(1,0)

chdir exepath() ' !!! for image loading be sure it's the right folder 
' in case of an desktop manager or file manager (windows linux mac) 
' if you click the binary with the mouse the current path must not be the path where you bmp's are 
' (it's more safe trust me)

color rgb(0,0,0),rgb(255,255,255):cls
greenBlob = imagecreate(96,128)
bload "greenBlob1.bmp",greenBlob

redPenguin = imagecreate(96,128)
bload "redPenguin1.bmp",redPenguin

dim shared as AGENT ag(0 to agentCount-1)

'skip player ag(0) and player(agentCount-1)
for i as integer = 1 to agentCount-1  
  ag(i).w = 32
  ag(i).h = 32
  ag(i).y = 0
  ag(i).x = i*TILEW*2
  ag(i).id = i
  ag(i).dx = int(rnd(1)*3)-1
  ag(i).dy = int(rnd(1)*3)-1
  while ag(i).dx = 0 andalso ag(i).dy=0
    ag(i).dx = int(rnd(1)*3)-1
    ag(i).dy = int(rnd(1)*3)-1
  wend
  ag(i).img = greenBlob
next i

ag(0).id = 0
ag(0).w = 32
ag(0).h = 32
ag(0).img = redPenguin

restore label_map ' !!! optinal but labels makes it more easy to extend it with more data fields
dim shared as integer world(WORLDW,WORLDH)
for j as integer = 0 to WORLDH-1
  for i as integer = 0 to WORLDW-1
    read world(i,j)
  next i
next j

function spriteCollision(b1 as AGENT,b2 as AGENT) as boolean
  ' andalso are faster only one fail are needed to go
  return (b2.y < (b1.y + b1.h) andalso (b2.y + b2.h) > b1.y andalso b2.x < (b1.x + b1.w) andalso (b2.x + b2.w) > b1.x)
end function

sub drawWorld()
  ' screenlock ' not needed if using a hidden page
  cls
  'draw tiles
  for j as integer = 0 to  WORLDH-1
    for i as integer = 0 to WORLDW-1
      if world(i,j)=1 then
        line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(100,100,200),bf
      elseif world(i,j)=2 then ' !!! added elsif 
        line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(200,100,100),bf
      end if
    next i
  next j
  'draw agents
  for i as integer = 0 to agentCount-1
    if ag(i).dx = 0 and ag(i).dy = 0 then ag(i).f = 1
    draw string (ag(i).x,ag(i).y),str(i)
    put (ag(i).x,ag(i).y),ag(i).img,(ag(i).f*32,ag(i).d*32)-(ag(i).f*32+31,ag(i).d*32+31),trans
  next i
  'screenunlock ' not needed if using a hidden page
  flip  ' !!! added make hidden page visible
end sub

sub makeMove(ag as AGENT)
  ag.x += ag.dx
  ag.y += ag.dy
end sub
   
function outOfBounds(ag as AGENT) as boolean
  ' !!! orelse faster only !!!one true!!! condition are needed
  if ag.x < 0 orelse ag.x > SCRW-TILEW orelse ag.y < 0 orelse ag.y > SCRH-TILEH then return TRUE
  return FALSE
end function

' !!! exit if one condition are true
function tileCollision(ag as AGENT) as boolean
    dim as integer TILEX,TILEY
    'test overlap of another tile
    TILEX = int(ag.x/TILEW)
    TILEY = int(ag.y/TILEH)
    if world(TILEX,TILEY)<>0 then return true

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y)/TILEH)
    if world(TILEX,TILEY)<>0 then  return true

    TILEX = int((ag.x)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then  return true

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then  return true
   
    return false
   
end function
       
sub undoMove(ag as AGENT)
  ag.x -= ag.dx 'undo move
  ag.y -= ag.dy
end sub
   
sub changeDirection(ag as AGENT)
  ag.dx = int(rnd(1)*3)-1
  ag.dy = int(rnd(1)*3)-1
  ' !!! andalso
  while (ag.dx andalso ag.dy) or (ag.dx=0 andalso ag.dy=0)
    ag.dx = int(rnd(1)*3)-1
    ag.dy = int(rnd(1)*3)-1
  wend
end sub
   
function onTile(ag as AGENT) as boolean
  ' !!! andalso
  if ag.x = int(ag.x\TILEW)*TILEW andalso ag.y = int(ag.y\TILEH)*TILEH then  return TRUE
  return FALSE
end function

sub setDirection(ag as AGENT)
  ' !!! added elsif eg. if dx<0 there is no need to test for if dx>0 also
  If ag.dx < 0 then
    ag.d = 1
  elseIf ag.dx > 0 then
    ag.d = 2
  end if  
  ' !!! added elsif eg. if dy<0 there is no need to test for if dy>0 also
  If ag.dy < 0 then
    ag.d = 3
  elseIf ag.dy > 0 then
    ag.d = 0
  end if
end sub

sub upDateFrame(ag as AGENT)
  ag.count = ag.count + 1
  if ag.count>10 then
    ag.count = 0
    ag.f = (ag.f + 1) mod 3 ' !!! added
    ' !!! removed if ag.f = 3 then ag.f = 0
  end if
end sub

sub update()
  for i as integer = 0 to agentCount-1
    makeMove(ag(i))

    ' !!! moved inside the loop scope and changed to boolean  
    dim as boolean hit = outOfBounds(ag(i))
    ' !!! only do a second test if first fails
    if hit = false then hit = tileCollision(ag(i))
       
    updateFrame(ag(i))

    if hit=false then ' !!! only if condition are false
      for j as integer = 0 to agentCount-1 'for each other sprite
        if i <> j then  'not with itself
          ' !!! exist if condition are true
          hit = spriteCollision(ag(i),ag(j)) 
          if hit then exit for
        end if
      next j
    end if  
       
    if hit = true then
      undoMove(ag(i))
      changeDirection(ag(i))
      setDirection(ag(i))
    end if
  next i
   
  ' read player agent(0) input if on center of tile
  if onTile(ag(0)) then
    ag(0).dx = 0
    ag(0).dy = 0
    'only one of four directions possible
    If MultiKey(&H4B) then ag(0).dx = -2 : ag(0).dy = 0
    If MultiKey(&H4D) then ag(0).dx =  2 : ag(0).dy = 0
    If MultiKey(&H48) then ag(0).dy = -2 : ag(0).dx = 0
    If MultiKey(&H50) then ag(0).dy =  2 : ag(0).dx = 0
    setDirection(ag(0))
  end if
end sub

dim as double now1
now1 = timer

update()
do
  if timer > now1 + 0.01 then
    now1 = timer
    update()
    drawWorld()
  end if
  sleep 10
loop until multikey(&H01)


label_map: ' optinal added
data 0,1,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,1,1,1,1,1,1,0,0,1,0
data 0,1,0,1,0,1,0,1,0,1,0,0,0
data 1,2,0,2,0,0,0,0,0,1,0,2,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 0,0,1,0,0,0,1,1,0,1,0,1,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 1,1,1,0,1,1,0,1,1,1,0,1,0
data 0,0,0,0,0,0,0,1,0,1,0,0,0
data 0,0,0,0,1,1,0,0,0,0,0,1,1
data 0,0,0,0,0,1,0,0,0,0,0,0,0
data 0,1,0,0,0,1,0,1,0,0,0,0,0
data 0,1,0,0,0,0,0,0,1,1,0,1,0
data 0,0,0,0,0,0,0,0,0,0,0,1,0
data 0,1,0,0,0,0,0,0,0,1,0,1,0

' label_more_data:
' data ...
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

@Joshy,
Thanks for the clean up and some interesting options and suggestions. Very educational.
With screenlock and using bitmaps I stopped using screenset and flip, something perhaps I should read up about again. Like someone with a poor vocabulary I tend to be lazy and just use the methods that I am familiar with as that means I at least know what is happening.
.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Simple Game framework

Post by BasicCoder2 »

So I have implemented pushing blocks. When the player is next to and facing a block hitting the SPACE BAR will cause the block to move off in that direction until it hits another block or the boundary.

Code: Select all

const WORLDW = 13
const WORLDH = 15
const TILEW = 32
const TILEH = 32
const SCRW = WORLDW*TILEW
const SCRH = WORLDH*TILEH

type AGENT
    as integer x         'current position
    as integer y
    as integer w
    as integer h
    as integer dx        'velocity between -1 and +1
    as integer dy
    as integer d         'direction
    as integer f         'current frame
    as integer tf        'total frames
    as integer count     'delay between frame increment
    as integer ID
    as any ptr img       'sprite image block
    as integer a
end type

dim shared as integer count  'frame delay

dim shared as integer blkID
dim shared as integer agentCount
agentCount = 5   'player = 0 and block = agentCount-1
blkID = agentCount-1

dim shared as integer WINX,WINY,WINW,WINH

screenres SCRW, SCRH, 32
color rgb(0,0,0),rgb(255,255,255):cls
chdir exepath() ' !!! for image loading be sure it's the right folder 

dim shared as any ptr block1
block1 = imagecreate(96,128)
'paint images in block
for j as integer = 0 to 3
    for i as integer = 0 to 2
        line block1,(i*32,j*32)-(i*32+31,j*32+31),rgb(255,i*100,0),bf
        line block1,(i*32,j*32)-(i*32+31,j*32+31),rgb(0,0,0),b
    next i
next j

dim shared as any ptr greenBlob
greenBlob = imagecreate(96,128)
bload "greenBlob1.bmp",greenBlob

dim shared as any ptr redPenguin
redPenguin = imagecreate(96,128)
bload "redPenguin1.bmp",redPenguin


dim shared as AGENT ag(0 to agentCount-1)

for i as integer = 1 to agentCount-2  'skip player ag(0) and player(agentCount-1)
    ag(i).w = 32
    ag(i).h = 32
    ag(i).y = 0
    ag(i).x = i*TILEW*2
    ag(i).id = i
    ag(i).dx = int(rnd(1)*3)-1
    ag(i).dy = int(rnd(1)*3)-1
    while ag(i).dx = 0 and ag(i).dy=0
        ag(i).dx = int(rnd(1)*3)-1
        ag(i).dy = int(rnd(1)*3)-1
    wend
    ag(i).img = greenBlob
    ag(i).a   = 1
next i

ag(0).id  = 0
ag(0).w   = 32
ag(0).h   = 32
ag(0).img = redPenguin
ag(0).a   = 1

ag(blkID).id   = blkID
ag(blkID).w    = 32
ag(blkID).h    = 32
ag(blkID).x    = 32
ag(blkID).y    = 0
ag(blkID).dx   = 0
ag(blkID).dy   = 0
ag(blkID).img  = block1
ag(blkID).a    = 0


dim shared as integer world(WORLDW,WORLDH)
for j as integer = 0 to WORLDH-1
    for i as integer = 0 to WORLDW-1
        read world(i,j)
    next i
next j

function spriteCollision(b1 as AGENT,b2 as AGENT) 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

sub drawWorld()
    screenlock
    cls
    'draw tiles
    for j as integer = 0 to  WORLDH-1
        for i as integer = 0 to WORLDW-1
            if world(i,j)=1 then
                line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(100,100,200),bf
            end if
            if world(i,j)=2 then
                line (i*TILEW,j*TILEH)-(i*TILEW+TILEW,j*TILEH+TILEH),rgb(200,100,100),bf
            end if
        next i
    next j
   
    'draw agents
    for i as integer = 0 to agentCount-1
        if ag(i).a = 1 then
            if ag(i).dx = 0 and ag(i).dy = 0 then ag(i).f = 1
            draw string (ag(i).x,ag(i).y),str(i)
            put (ag(i).x,ag(i).y),ag(i).img,(ag(i).f*32,ag(i).d*32)-(ag(i).f*32+31,ag(i).d*32+31),trans
        end if
    next i

    screenunlock
    
end sub

sub makeMove(ag as AGENT)
    ag.x = ag.x + ag.dx
    ag.y = ag.y + ag.dy
end sub
    
function outOfBounds(ag as AGENT) as boolean
    if ag.x < 0 or ag.x > SCRW-TILEW or ag.y < 0 or ag.y > SCRH-TILEH then
        return TRUE
    else
        return FALSE
    end if
end function

function tileCollision(ag as AGENT) as boolean
    dim as boolean hit
    dim as integer TILEX,TILEY
    'test overlap of another tile
    TILEX = int(ag.x/TILEW)
    TILEY = int(ag.y/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1

    TILEX = int((ag.x+TILEW-1)/TILEW)
    TILEY = int((ag.y+TILEH-1)/TILEH)
    if world(TILEX,TILEY)<>0 then hit = 1
    
    return hit
    
end function
       
sub undoMove(ag as AGENT)
    ag.x = ag.x - ag.dx 'undo move
    ag.y = ag.y - ag.dy
end sub
    
sub changeDirection(ag as AGENT)
    ag.dx = int(rnd(1)*3)-1
    ag.dy = int(rnd(1)*3)-1
    while (ag.dx and ag.dy) or (ag.dx=0 and ag.dy=0)
        ag.dx = int(rnd(1)*3)-1
        ag.dy = int(rnd(1)*3)-1 
    wend
end sub
    
function onTile(ag as AGENT) as boolean
    if ag.x = int(ag.x\TILEW)*TILEW and ag.y = int(ag.y\TILEH)*TILEH then
        return TRUE
    else
        return FALSE
    end if
end function

sub setDirection(ag as AGENT)
    If ag.dx < 0 then ag.d = 1
    If ag.dx > 0 then ag.d = 2
    If ag.dy < 0 then ag.d = 3
    If ag.dy > 0 then ag.d = 0 
end sub

sub upDateFrame(ag as AGENT)
    ag.count = ag.count + 1
    if ag.count>10 then
        ag.count = 0
        ag.f = ag.f + 1
        if ag.f = 3 then ag.f = 0
    end if
end sub

sub update()
    dim as integer hit
    
    for i as integer = 0 to agentCount-1
        
        if ag(i).a = 1 then
        
            hit = 0
        
            makeMove(ag(i))
        
            if outOfBounds(ag(i)) then
                hit = 1
            end if
        
            if tileCollision(ag(i)) then
                hit = 2
            end if
        
            updateFrame(ag(i))
        
            for j as integer = 0 to agentCount-1 'for each other sprite
                if i <> j then  'not with itself
                    if ag(j).a = 1 then 'it exists
                        if spriteCollision(ag(i),ag(j)) = TRUE then
                            hit = 3
                        end if
                    end if
                end if
            next j
        
            if hit <> 0 then
                
                if i = blkID then
                    if hit = 1 or hit = 2 then 
                        undoMove(ag(blkID))
                        ag(blkID).a = 0
                        world(ag(blkID).x\TILEW,ag(blkID).y\TILEH)=1
                    end if
                else
                   undoMove(ag(i))
                   if i<>0 then  'not player
                       changeDirection(ag(i))
                       setDirection(ag(i))
                   end if
               end if
    
            end if
        end if
        
    next i
    
    'read player input if on center of tile
    if onTile(ag(0)) then
        
        ag(0).dx = 0
        ag(0).dy = 0
        'only one of four directions possible
        If MultiKey(&H4B) then ag(0).dx = -2:ag(0).dy = 0
        If MultiKey(&H4D) then ag(0).dx =  2:ag(0).dy = 0
        If MultiKey(&H48) then ag(0).dy = -2:ag(0).dx = 0
        If MultiKey(&H50) then ag(0).dy =  2:ag(0).dx = 0
        setDirection(ag(0))
        
        if multikey(&H39) then
            if ag(0).d = 0 and world(ag(0).x\TILEW,ag(0).y\TILEH+1)<>0 then  'moving down
                world(ag(0).x\TILEW,ag(0).y\TILEH+1)=0
                ag(blkID).dy = 1
                ag(blkID).dx = 0
                ag(blkID).a = 1
                ag(blkID).x = ag(0).x
                ag(blkID).y = ag(0).y+32
            end if
            if ag(0).d = 1 and world(ag(0).x\TILEW-1,ag(0).y\TILEH)<>0 then 'moving left
                world(ag(0).x\TILEW-1,ag(0).y\TILEH)=0
                ag(blkID).dx = -1
                ag(blkID).dy = 0
                ag(blkID).a = 1
                ag(blkID).x = ag(0).x-32
                ag(blkID).y = ag(0).y
            end if
            if ag(0).d = 2 and world(ag(0).x\TILEW+1,ag(0).y\TILEH)<>0 then 'moving right
                world(ag(0).x\TILEW+1,ag(0).y\TILEH)=0
                ag(blkID).dx = 1
                ag(blkID).dy = 0
                ag(blkID).a = 1
                ag(blkID).x = ag(0).x+32
                ag(blkID).y = ag(0).y
            end if
            if ag(0).d = 3 and world(ag(0).x\TILEW,ag(0).y\TILEH-1)<>0 then 'moving up
                world(ag(0).x\TILEW,ag(0).y\TILEH-1)=0
                ag(blkID).dy = -1
                ag(blkID).dx = 0
                ag(blkID).a = 1
                ag(blkID).x = ag(0).x
                ag(blkID).y = ag(0).y - 32
            end if
        end if        

    end if
    
    
end sub



dim as double now1
now1 = timer

update()

do
   
    if timer > now1 + 0.01 then
        now1 = timer
        update()
        drawWorld()
    end if
   
    sleep 2

loop until multikey(&H01)

data 0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,1,1,1,1,1,1,0,0,1,0
data 0,1,0,1,0,1,0,1,0,1,0,0,0
data 1,2,0,2,0,0,0,0,0,1,0,2,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 0,0,1,0,0,0,1,1,0,1,0,1,0
data 1,0,0,0,0,0,0,0,0,1,0,1,0
data 1,1,1,0,1,1,0,1,1,1,0,1,0
data 0,0,0,0,0,0,0,1,0,1,0,0,0
data 0,0,0,0,1,1,0,0,0,0,0,1,1
data 0,0,0,0,0,1,0,0,0,0,0,0,0
data 0,1,0,0,0,1,0,1,0,0,0,0,0
data 0,1,0,0,0,0,0,0,1,1,0,1,0
data 0,0,0,0,0,0,0,0,0,0,0,1,0
data 0,1,0,0,0,0,0,0,0,1,0,1,0
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Simple Game framework

Post by leopardpm »

why not implement the block push when checking collison between player and block? if he collideds with block, and there is no block behind it then it slides... seems easier, but.... maybe not - that way there is not another key to press, just movement

just a thought
Post Reply