Main Menu

For Foxes Sake WIP

Started by micky4fun, August 19, 2012, 03:54:41 AM

Previous topic - Next topic

BlinkOk

it looks brilliant mick. excellent work. i'll do a box.
do you want flowers and a watering can?

micky4fun

hi all

hi BlinkOk , yep have a box , flowers and watering can , will break it up a bit more , i did multicolour stars for fence , so maybe could do a fence once painted has a few coloured spots on it

mick :)

BlinkOk

#92
this is the fence and fiddling with bits here and there
i'm sorry i've given you stuff in such and awkward format.
must be a pain to chop it up and format it.
i'll try and make it easier from here on

ps: there's an "open" chest image in the 217o.png image you can use (don't know why that isn't in the 217.png image)
pps: updated a little (better fish). there are two frames for going up and two frames for going down

kevin


  The new version is excellent,  only a few niggles,  I'd soften the attachment between the camera and the player just a little bit, so it doesn't feel so linear.   The only things  I'm a bit worried about the character placement and  controller stuff has hard coded decisions built into it.   

  What I'm talking about are loops like this.   

PlayBASIC Code: [Select]
  ;-------------------------------------   enimies controller -------------------------------------------
for lp=1 to NumberofEnimies
dogs(lp).thisangle#=dogs(lp).Angle#
dogs(lp).orbitx#=dogs(lp).mx#+(Cos(dogs(lp).thisangle#)*dogs(lp).RadiusX)
dogs(lp).orbity#=dogs(lp).my#+(Sin(dogs(lp).thisangle#)*dogs(lp).RadiusY)
positionsprite dogs(lp).sprite,dogs(lp).orbitx#,dogs(lp).orbity#
dogs(lp).Angle#=WrapAngle(dogs(lp).Angle#,dogs(lp).spd_rotate#)
if lp<7 ; less than 7 are snails
if dogs(lp).angle#<180 then dogs(lp).increase=0
if dogs(lp).angle#>180 then dogs(lp).increase=10
dogs(lp).animation#=dogs(lp).animation#+0.20
if dogs(lp).animation#>9 then dogs(lp).animation#=0
endif
if lp>6; more that 6 are fish
if dogs(lp).angle#>240
dogs(lp).animation#=dogs(lp).animation#+0.25
if dogs(lp).animation#>9 then dogs(lp).animation#=9
endif
if dogs(lp).angle#<90
dogs(lp).animation#=dogs(lp).animation#-0.25
if dogs(lp).animation#<0 then dogs(lp).animation#=0
endif
endif
spriteimage dogs(lp).sprite,dogs(lp).image+dogs(lp).increase+dogs(lp).animation#
next lp


   

      Here's we've a loop that's assuming the position in the array as they character type.  So every time we change the characters in the level we've got to alter this code.   Which make more maintenance for us and is ultimately error prone.   

      A much better and easier to maintain solution is to add  'controller type' or "ai type'  field to the character structure.       

PlayBASIC Code: [Select]
   type plats
CharacterType
thisangle#
animation#
increase
image
angle#
orbitx#
orbity#
spd_rotate#
radiusx
radiusy
sprite
mx#,my#
endtype




     When we create the character (fill in it's structure) and set it's character type.  Let say 1 is a dog and 2 is the snail,  3 could be a chicken, 4 could be horse etc.. So each character type has it's own unique controller type value.   

     so when we process the characters in the dogs() array,  we're looking at each items characterType field to determine what controller code to use.   Now it doesn't matter, how many are in the array, what order they're in.  or if any have died.. 

     Like this.

PlayBASIC Code: [Select]
  ;-------------------------------------   enimies controller -------------------------------------------
for lp=1 to Getarrayelements(Dogs())
; check if this character even exists.. If it's zero, it doesn't, so skip it
if Dogs(lp)

; Select What controller code we should run (or character type this thing is)
Select Dogs(lp).CharacterType


; ------------------------------
case 1 ; DOG
; ------------------------------

; if we stored a 1 in the CharacterType field. then it'll run this code
; and when it's done, jump down to the END SELECT statement

dogs(lp).thisangle#=dogs(lp).Angle#
dogs(lp).orbitx#=dogs(lp).mx#+(Cos(dogs(lp).thisangle#)*dogs(lp).RadiusX)
dogs(lp).orbity#=dogs(lp).my#+(Sin(dogs(lp).thisangle#)*dogs(lp).RadiusY)
positionsprite dogs(lp).sprite,dogs(lp).orbitx#,dogs(lp).orbity#
dogs(lp).Angle#=WrapAngle(dogs(lp).Angle#,dogs(lp).spd_rotate#)

if dogs(lp).angle#<180 then dogs(lp).increase=0
if dogs(lp).angle#>180 then dogs(lp).increase=10
dogs(lp).animation#=dogs(lp).animation#+0.20
if dogs(lp).animation#>9 then dogs(lp).animation#=0

spriteimage dogs(lp).sprite,dogs(lp).image+dogs(lp).increase+dogs(lp).animation#

; ------------------------------
case 2 ; Snail
; ------------------------------


dogs(lp).thisangle#=dogs(lp).Angle#
dogs(lp).orbitx#=dogs(lp).mx#+(Cos(dogs(lp).thisangle#)*dogs(lp).RadiusX)
dogs(lp).orbity#=dogs(lp).my#+(Sin(dogs(lp).thisangle#)*dogs(lp).RadiusY)
positionsprite dogs(lp).sprite,dogs(lp).orbitx#,dogs(lp).orbity#
dogs(lp).Angle#=WrapAngle(dogs(lp).Angle#,dogs(lp).spd_rotate#)

if dogs(lp).angle#>240
dogs(lp).animation#=dogs(lp).animation#+0.25
if dogs(lp).animation#>9 then dogs(lp).animation#=9
endif
if dogs(lp).angle#<90
dogs(lp).animation#=dogs(lp).animation#-0.25
if dogs(lp).animation#<0 then dogs(lp).animation#=0
endif
endif
spriteimage dogs(lp).sprite,dogs(lp).image+dogs(lp).increase+dogs(lp).animation#


; ------------------------------
case 3 ; Horse or
; ------------------------------


; ------------------------------
case 4 ; some other character type
; ------------------------------



EndSelect


endif

next lp





     In this version we're make the code more generic and change resistant.  It no longer matters what order the characters are created in, if the character exists, and we can handle every different unique character type with it's only custom controller code. 

     To get rid of the character type numbers and replace them names we can define a set of constants.    This helps in the readability of the program dramatically and it means we can add and change the order of the characters whenever we like.

PlayBASIC Code: [Select]
    Constant CharacterType_Dog =1
Constant CharacterType_Snail=2
Constant CharacterType_Horse=3
Constant CharacterType_SomeOtherThing=4
etc
etc





Sigtrygg

Hello Mick!

Fantastic looking game! Great animations!
You have a hand for atmosphere. I love the snails!
I wish I could handle such map and character
animations. But I hope to learn further. That's
fun for me, too.

Greetings

Sigtrygg

micky4fun

#95
Hi all

Thanks for advice on handling enimies Kevin , now implimented this into game , apart from chickens and horse lol , chickens maybe ?, anyway works a treat , also have added you now can kill enimies when you jump or fall on them , as you can see still loads and loads to do , will do bit and bobs as i go but trying to spend as much time as i can on it

thanks BlinkOk for latets gfx's , they seem to work fine , will let you know what else is needed , you did say game keeper with gun up  to you ? and the watering can and flowers , they spring up when watered ?

QuoteI love the snails!
yep Sigtrygg , took me ages to draw these , yeh cousre it did , yep BlinkOk made a great job on the snails my favourites to
QuoteI wish I could handle such map and character
animations.
not a great deal to what i have done really , maybe better ways of doing it , but seems to work in this game , just trial and error you will soon suss it out

mick :)

BlinkOk

#96
Quoteyou did say game keeper with gun up  to you ? and the watering can and flowers , they spring up when watered ?
yeah i'll get those done today

ps: flowers and watering can.
pps: hunter dude

micky4fun

Hi all

Thanks for new stuff BlinkOk , not got them in game yet , just wanted to post were i am at today , after a little tiding up in code and putting Kevins ideas in code as well ,
just wondering if all the enimies are ok all being purple , as i thought they seem to blend together a bit , what do you think ?
also you can just do the images the size they are if you want , ie dog takes up 64x64 nearly double , this proberly dont matter but may run it quicker on old machine , though it flys on mine at 486 fps
errm bad news if i use watering can may need for animation of him walking with it ? , wont do anymore pick ups that he uses , wont matter with key etc , could have little hud on screen for that

will do the chest opens to reveal paint brush , that not done yet ,
only got a few hours in today,

you can now kill the 15 enimies on screen , but they cannot kill you , proberly have a energy bar at top of screen so when you get touched by enimies it goes down , or something like that

ok thats it i think ,
mick :)

BlinkOk

ok mick i'll have a look at the colours and resize the sprites.

kevin


  Version 9 plays really well,   found myself playing through looking for stuff to jump on.    Your updated character controller code is much, much better ! -  The other part that's worth cleaning up when looking forward is the character creation method.     

 
PlayBASIC Code: [Select]
   NumberofENIMIES=15
dim dogs as plats list
for a=1 to numberofenimies
dogs = new plats
dogs.sprite=getfreesprite()
createsprite dogs.sprite
spriteimage dogs.sprite,401
centerspritehandle dogs.sprite
spritecollisionclass dogs.sprite,4
spritecollisionmode dogs.sprite,6

if a=1 then dogs.radiusy=0:dogs.radiusx=140:dogs.my=685:dogs.mx=560:dogs.spd_rotate#=0.3:dogs.angle#=0:dogs.image=401:dogs.object=chr_snail
if a=2 then dogs.radiusy=0:dogs.radiusx=140:dogs.my=685:dogs.mx=560:dogs.spd_rotate#=0.3:dogs.angle#=180:dogs.image=401:dogs.object=chr_snail
if a=3 then dogs.radiusy=0:dogs.radiusx=100:dogs.my=621:dogs.mx=317:dogs.spd_rotate#=0.4:dogs.angle#=90:dogs.image=401:dogs.object=chr_snail
if a=4 then dogs.radiusy=0:dogs.radiusx=120:dogs.my=109:dogs.mx=225:dogs.spd_rotate#=0.4:dogs.angle#=180:dogs.image=401:dogs.object=chr_snail
if a=5 then dogs.radiusy=0:dogs.radiusx=200:dogs.my=685:dogs.mx=1230:dogs.spd_rotate#=0.4:dogs.angle#=180:dogs.image=401:dogs.object=chr_snail
if a=6 then dogs.radiusy=0:dogs.radiusx=130:dogs.my=557:dogs.mx=1695:dogs.spd_rotate#=0.3:dogs.angle#=180:dogs.image=401:dogs.object=chr_snail


if a=7 then dogs.radiusy=170:dogs.radiusx=0:dogs.my=800:dogs.mx=833:dogs.spd_rotate#=1.5:dogs.angle#=180:dogs.image=421:dogs.object=chr_fish
if a=8 then dogs.radiusy=170:dogs.radiusx=0:dogs.my=800:dogs.mx=898:dogs.spd_rotate#=1.5:dogs.angle#=300:dogs.image=421:dogs.object=chr_fish
if a=9 then dogs.radiusy=220:dogs.radiusx=0:dogs.my=800:dogs.mx=3080:dogs.spd_rotate#=1.5:dogs.angle#=300:dogs.image=421:dogs.object=chr_fish
if a=10 then dogs.radiusy=220:dogs.radiusx=0:dogs.my=800:dogs.mx=3200:dogs.spd_rotate#=1.5:dogs.angle#=180:dogs.image=421:dogs.object=chr_fish
if a=11 then dogs.radiusy=0:dogs.radiusx=200:dogs.my=407:dogs.mx=1984:dogs.spd_rotate#=0.8:dogs.angle#=180:dogs.image=431:dogs.object=chr_dog
if a=12 then dogs.radiusy=0:dogs.radiusx=280:dogs.my=662:dogs.mx=2140:dogs.spd_rotate#=0.6:dogs.angle#=270:dogs.image=431:dogs.object=chr_dog
if a=13 then dogs.radiusy=0:dogs.radiusx=280:dogs.my=662:dogs.mx=2140:dogs.spd_rotate#=0.6:dogs.angle#=90:dogs.image=431:dogs.object=chr_dog
if a=14 then dogs.radiusy=0:dogs.radiusx=280:dogs.my=662:dogs.mx=2140:dogs.spd_rotate#=0.6:dogs.angle#=180:dogs.image=431:dogs.object=chr_dog
if a=15 then dogs.radiusy=0:dogs.radiusx=140:dogs.my=621:dogs.mx=2240:dogs.spd_rotate#=0.5:dogs.angle#=180:dogs.image=401:dogs.object=chr_snail
next a




    This works, BUT, as the game grows and more characters are added, or changes are required etc etc, it means we're back man handling the codes on a one to basis.  If we have a 100 characters in the level,  and need to change something..  We're making 100 changes.. Not ideal..     But really this is really a situation to wrap up the 'creation' process for a each different character type the game has into separate functions.

     We can give the function/pubs  meaningful name and only pass in the 'variables' this character type needs.  Anything that's know is preset inside the function.  So it's character type, it's sprite,  perhaps it's score values in the future and whatever else..   


    (puesdo code mainly)

PlayBASIC Code: [Select]
   ; You can do this with a generic 'add character' routine where you pass all the characters fields into one function..  
; but it's generally easier to set up the function/sub up you only pass it the parameter required. So any time you
; every want to add this type of character, you just call the function.


Psub Add_Snail(Xpos,Ypos,RAdiusX,Speed#,Angle#)
; Add to our list called dogs
dogs = new plats

; Set it character type/class
dogs.object=chr_snail

; since all the sprites have the same properties, i've wrapped up the sprite creation code into a generic
; so any time we need a new game sprite, we call it and get a sprite set up the way we require every time.

Image=421
dogs.image=Image
Dogs.Sprite= MakeCharacterSprite(IMage)


dogs.mx=Xpos
dogs.my=Ypos
dogs.radiusx=RAdiusX
; dogs.radiusy=0 ; we when create a type, all the fields in the type are zero, we don't actually need to set to zero explicitly
dogs.spd_rotate#=Speed#
dogs.angle#=Angle#

EndPsub



Psub Add_Fish(Xpos,Ypos,RAdiusX,RadiusY,Speed#)
; Add to our list called dogs
dogs = new plats

dogs.object=chr_Fish

Image=401
dogs.image=Image
Dogs.Sprite= MakeCharacterSprite(IMage)


dogs.mx=Xpos
dogs.my=Ypos
dogs.radiusX=RAdiusX
dogs.radiusY=RAdiusX
dogs.spd_rotate#=Speed#
dogs.Angle=Angle#

EndPsub



Psub MakeCharacterSprite(IMage)

ThisSprite=getfreesprite()
createsprite ThisSprite
spriteimage ThisSprite,IMage
centerspritehandle ThisSprite
spritecollisionclass ThisSprite,4
spritecollisionmode ThisSprite,6

EndPSub ThisSprite



   

    Anyway, what this means is we can create our characters more like this.

PlayBASIC Code: [Select]
   ; so this
; if a=1 then dogs.radiusy=0:dogs.radiusx=140:dogs.my=685:dogs.mx=560:dogs.spd_rotate#=0.3:dogs.angle#=0:dogs.image=401:dogs.object=chr_snail

;adding this snail
Add_Snail(560,685,120,0.3,0)

etc etc
Add_Snail(560,685,120,0.3,0)
Add_Snail(560,685,120,0.3,180)




     Not only to we get less code to maintain,  what we're actually doing is creating our own 'game interface'.   Which is nothing more that hiding the repe3ative code inside functions/psubs.    If we cast our minds forward to externalizing the character data to disk,  then you only have to store the unique 'fields' of each character type.    So in the snails case that's it's X,Y, RadiusX, Speed# and Angle# .




ATLUS

#100
micky4fun and blinkok this game is better and better! you guys is amazing!

micky4fun

Hi All

Thanks for code snippet again Kevin , yes i see what you mean , make it a lot easier to drop them in , if i was cleaver enough i know it could be done in a map editor , but i might have a stab at that if i get a spare few hours see how i go ,

BlinkOk , i have cropped dog images so they are ok , just added clouds , kevins snippets , very slight level change , and few other bits today , so will crack on again in spare time tomorrow .

Thanks ATLAS , well looks a million times better with BlinkOks gfx's and as said before your orbit snippet has come in very handy again for me , used it in egg selector as well
dont just work with circles

mick :)

stevmjon

hey micky4fun

this is entertaining to play.  i love the character movements and animation, especially the dog. i like how blinok made it bounce as it walks.

i thought for something to add is a fence counter on screen, so the player knows how many are remaining in the level that need painting.

keep up the good work, as this is really growing.

  stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

kevin


QuoteThanks for code snippet again Kevin , yes i see what you mean , make it a lot easier to drop them in , if i was cleaver enough i know it could be done in a map editor , but i might have a stab at that if i get a spare few hours see how i go

   You've got all the info, it's a matter of tacking it all together.   What i'd do in the editor is split the process into two modes.  Mode 1 is regular map editing mode, nothing changes.   Mode 2  would be character placement mode.   

   When in placement mode,  the level maker can still scrolling around the map  but this time we're dropping 'character' markers, rather than drawing blocks on the map.  You could load in a single frame (or all frames) of each character type and display them across the top of the map, it'd be just like the block selection.     

   Depending upon how the character AI works which I think it's mainly circle based.  So when you drop a character into the world, you'd be setting it's base/axis position.  So we still need to edit it's radius and speed.  The dropper could work out the radius by counting the blocks to Left and right under this position.   Or you can could manually size a circle.   Having it work out the radius from the map is prolly the better idea, given how many characters will need to be placed.  Still much easier to programming them hand.         

   What i would most like do, is include various character editing modes.   So there could be a simple drop mode, where you select the dude from the character palette at the top, then splodge them where ever you want around the world.  There would also need to be a edit character mode.  In this mode, the program wants you to select the character (by clicking on it), once selected,  it might show a circle for it's movement path,  or display some text message with the speed or whatever on screen in front of you.    To alter the values you might just have some keys, or use the mouse wheel/buttons whatever.

   Anyway,  as for exporting the data.  We just save a file with important fields for each character type.    So the editor has the characters in an array/list whatever, and we just run through that list to save them out.   Much much like changes you've made to character handler.

    The character file just needs the character type, and this character position/radius speed whatever.  Bellow we have  a mock up of how the data is stored, an example saver and loader routine for the 'game'   using the wrapped character creation functions.     I would make create function for everything.    I'd then simply split this code into a separate file and have both the editor and game use the same file.   

PlayBASIC Code: [Select]
   Constant CharacterType_ENDOFCHARACTERS   =-1
Constant CharacterType_Player =0
Constant CharacterType_Dog =1
Constant CharacterType_Snail =2


Type CharacterInfo
MyType
X#,Y# ; position
RadiusX#,RadiusY#
Speed#
EndType

Dim Character(0) as CharacterInfo


; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; Save Charcters function in the EDITOR
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------

Function SaveCharacters(Filename$)

Fh=WriteNewFile(filename$)

For lp=1 to GetArrayElements(Character())
if Character(lp)

; Write the character type to the file. So when we read this back, we know what type the next section of data is.
WriteInt fh, Character(lp).MyType

Select Character(lp).MyType


case CharacterType_PLayer

WriteFloat fh,Character(lp).X#
WriteFloat fh,Character(lp).Y#
; Starting position plus whatever else it needs to know


case CharacterType_Dog
; write floats, if the fields are floats and integer when they're integers
WriteFloat fh,Character(lp).X#
WriteFloat fh,Character(lp).Y#
WriteFloat fh,Character(lp).RadiusX#
WriteFloat fh,Character(lp).Speed#


case CharacterType_Snail

WriteFloat fh,Character(lp).X#
WriteFloat fh,Character(lp).Y#
WriteFloat fh,Character(lp).RadiusX#
WriteFloat fh,Character(lp).Speed#

EndSelect

endif
next


; put the end of characters marketer at the end of the file, you could also
; just use the files length.
writeint fh,CharacterType_ENDOFCHARACTERS

closefile fh

EndFunction





; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; Load Characters function which would go in the game.
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------
; -----------------------------------------------------------------------

Function LoadCharacters(Filename$)




Fh=readNewFile(filename$)


repeat
CharacterType=ReadInt(fh)

Select CharacterType

case CharacterType_PLayer

x#=Readfloat(fh)
y#=Readfloat(fh)

// wrap all the player initialization stuff upon
Position_player(X#,y#)


case CharacterType_Dog
; write floats, if the fields are floats and integer when they're integers
x# =Readfloat(fh)
y# =Readfloat(fh)
RadiusX# =Readfloat(fh)
Speed# =Readfloat(fh)

; now we just call our wrapped add dog function.
Add_Dog(x#,y#,RAdiusX#,Speed#)


case CharacterType_Snail

; write floats, if the fields are floats and integer when they're integers
x# =Readfloat(fh)
y# =Readfloat(fh)
RadiusX# =Readfloat(fh)
Speed# =Readfloat(fh)

; now we just call our wrapped add snail function.
Add_Snail(x#,y#,RAdiusX#,Speed#)

EndSelect


until CharacterType=CharacterType_ENDOFCHARACTERS

closefile fh

EndFunction







   

micky4fun

Hi all

thanks Kevin , for advice and mock up , i will give it a whirl when i have a few hours spare , i did get an hour or so but really kept on tring a few things out in game ,

Hi BlinkOk , i have gone with this idea for getting brush , hope that it looks ok , got clouds and larger fish in , but not done all ani frames yet on those , will use both fish i think , only kill larger ones on way down i think , that bit not done eithet yet , tried a few things with water as it would run different depending which way you ran ,

thanks stevmjon , yep was going to do a way of counting fences say 100 per level and 100 coins or there abouts so you know theres some left , yep BlinkOk keeps suprizing us with all the good gfx's that for sure

back soon
mick :)

heres an uptodate version ,