Hi
I am building an Arcade Shooter - but find that my enemies (which I iterate thru to update their positions) start off nice and quick and so does my player ships and firing etc...
But when enemies are reduces to 4 or less the game crawls!
I suspect it is due to the foreach enemy Loop i have and as it reduces the showscreen fires more often and so does my check for collisions and check for key press events...
Any ideas how I could go about sorting this??
I have put in a framerate timer but that is not helping...
That's an odd one. One thing you can do is to set the profiler to active when in debug mode. It will create a MS excel file in your game's app folder with a run down of how much time each of your functions takes. In the drop down menu you'll find it in Compiler -> Profiler -> Active.
Hopefully that should help you determine for sure which function is causing things to slow down.
Are you sure you're not constantly creating multiple instances of a TYPE and not removing/destroying them? Eg the bullets? You could have thousands of bullets off of the screen still being iterated through. Or something like that?
Something is triggering a red flag here. "... the showscreen fires more often and so does my check for collisions and check for key press events..." the showscreen and check for collision / key events should have NOTHING to do with a loop drawing and handling enemy AI. I'd need to see some code in order to help you, sounds like you've tangled some functions together...
DELETE the shots and the Enemys if they offscreen!
Guys,
Thanks for the suggestions....I am getting weird occurances...
I am deleting the shots and the enemies but and very strange is my ship suddenly runs out of bullets!!!
I havent got a clue whats causing that...
Here's my *ahem* code... not pretty......in order to keep speed constant i ended up not deleting the enemies but flagged them as no-longer-required...I shouldnt have to but that kept the game running at the same speed...
LOADSOUND "zap1.wav", 0, 2
LOADSOUND "zap2.wav", 1, 4
PLAYSOUND (0, 1, .2)
SHOWSCREEN
KEYWAIT
GLOBAL score%
// start
score = 0
lasttime = 0
speed#=0.0
GLOBAL ssx,ssy
GETSCREENSIZE ssx,ssy
lasttime = GETTIMERALL()
GOSUB main
END
SUB restarting:
IF score > 0 THEN GOTO skipdims
// START AND DEFINITIONS
LIMITFPS 60
//SETTRANSPARENCY RGB(128,0,128)
//LOADSPRITE "inv2.bmp",1
LOADSPRITE "tie.png",1
//LOADSPRITE "shp.bmp",0
LOADSPRITE "shot.png",3
//LOADSPRITE "shot2.bmp",2
LOADSPRITE "enemyshot.png",2
LOADANIM "inv3.png",4,32,32
LOADANIM "shootsprite.png",10,30,30
LOADSPRITE "player1.png",0
TYPE starfield
x% =0
y%= 0
s=0.0
ENDTYPE
GLOBAL stars[] AS starfield
TYPE enemy
x%=0
y%=0
hits% = 1
col=3
spr% = 1
dirx = 1
stat%=0
ENDTYPE
GLOBAL invader[] AS enemy
TYPE ship
x% = 32
y%=440
lives = 3
spr = 0
ENDTYPE
GLOBAL shp AS ship
TYPE shot
x% = 0
y% = 0
hit = 0
spr = 3
ENDTYPE
TYPE shot2
x% = 0
y% = 0
hit = 0
spr = 2
ENDTYPE
GLOBAL shots[] AS shot
GLOBAL shots2[] AS shot2
createstars(50)
skipdims:
REDIM invader[0]
REDIM shots[0]
REDIM shots2[0]
FOR m = 32 TO 256 STEP 48
FOR n = 32 TO 256 STEP 48
LOCAL newi AS enemy
newi.x = n
newi.y = m
newi.spr = 1
DIMPUSH invader[],newi
NEXT
NEXT
drawinv()
SHOWSCREEN
ENDSUB
// main loop **************************************
SUB main:
GOSUB restarting
scre = 0
IF LEN(invader[])-1 = 0
LOCAL scre% = score
ENDIF
IF scre > 0 THEN score% = scre
// start timer
initAppTime()
WHILE TRUE
moveall()
//SLEEP 1000
a$=INKEY$()
IF a$ = "q" THEN END
WEND // end of program
ENDSUB
// **************************************************************
// ALL FUNCTIONS
// **************************************************************
FUNCTION drawinv:
// both bullet types
FOREACH bul IN shots[]
DRAWSPRITE bul.spr,bul.x,bul.y
NEXT
FOREACH bul2 IN shots2[]
DRAWSPRITE bul2.spr,bul2.x,bul2.y
NEXT
// only animate once per loop
IF anim% = 1 AND an% = 20
anim% = 2
an%=0
ELSE
anim% = 1
an% = an% + 1
ENDIF
FOREACH inv IN invader[]
// DRAWSPRITE inv.spr,inv.x,inv.y
// IF inv.stat=0 THEN DRAWANIM 4,anim%,inv.x,inv.y
IF inv.stat=0 THEN DRAWSPRITE inv.spr,inv.x,inv.y
NEXT
DRAWSPRITE shp.spr,shp.x,shp.y
//Score
PRINT "score: " + score%,30,30
PRINT "lives: " + shp.lives,30,50
PRINT LEN(shots[])-1,30,70
PRINT "ATTACK OF THE KILLER 'CLOWNS'",30,6
//IF delay > 200
FOREACH star IN stars[]
DRAWRECT star.x,star.y,1,1,RGB(250,250,250)
INC star.y, star.s
//INC star.y, RND(4)*speed
IF star.y > ssy+10 THEN star.y = 5
NEXT
// ENDIF
ENDFUNCTION
FUNCTION moveall:
elapsed% = GETTIMERALL()- lasttime
//fract = MOD (elapsed,100)
//fract2 = MOD (elapsed,10)
// DEBUG fract
//IF fract = 0 THEN RETURN
FOR bull = 0 TO BOUNDS(shots[],0)-1
shots[bull].y = shots[bull].y - 6
IF shots[bull].y < 100 THEN DIMDEL shots[],bull
NEXT
FOREACH ns IN shots2[]
ns.y = ns.y + 6
IF ns.y > 470 THEN DELETE ns
NEXT
indx = LEN(invaders[])-1
// firing for aliens
FOREACH inv2 IN invader[]
chancetoshoot% = RND(500)+1
// iterated
//IF inv2.stat% = 0
IF chancetoshoot% = indx AND inv2.stat = 0
LOCAL newshot AS shot2
newshot.x = inv2.x + 10
newshot.y = inv2.y
DIMPUSH shots2[],newshot
PLAYSOUND (1, 0, .5)
ENDIF
// move in left dir
IF inv2.dirx = 1
inv2.x = inv2.x + (4* speed)
ENDIF
// move in left dir
IF inv2.dirx = 0
inv2.x = inv2.x - (4* speed)
ENDIF
//move down if over far enough and upd dir for all
IF inv2.x >= (640-16) AND inv2.stat = 0
FOREACH upd IN invader[]
IF stat = 0
upd.y = upd.y + 16
upd.dirx = 0
ENDIF
NEXT
ENDIF
//move down if over far enough and upd dir for all
IF inv2.x <= (32) AND inv2.stat = 0
FOREACH upd2 IN invader[]
IF stat = 0
upd2.y = upd2.y + 16
upd2.dirx = 1
ENDIF
NEXT
ENDIF
// ENDIF // top if
INC indx
checkkeys()
checkhits()
NEXT
drawinv()
// checkkeys()
SLEEP 1
speed = updateAppTime()
SHOWSCREEN
ENDFUNCTION
FUNCTION checkkeys:
// IF KEY(203) THEN shp.x = shp.x - (1 + (KEY(205) - KEY(203)*2))
// IF KEY(205) THEN shp.x = shp.x + (1 + (KEY(205) - KEY(203)*2))
INC shp.x, (KEY(205)-KEY(203))*3*speed
IF KEY(57) AND delay=0
LOCAL bullet AS shot
bullet.x = shp.x + 10
bullet.y = shp.y - 16
DIMPUSH shots[],bullet
delay = 600*speed
PLAYSOUND (0, 1, 1)
ENDIF
IF delay > 0 THEN DEC delay
ENDFUNCTION
FUNCTION checkhits:
FOR sh = 0 TO LEN(shots[])-1
remshot = -1
FOR en = 0 TO LEN(invader[])-1
IF BOXCOLL(shots[sh].x,shots[sh].y,6,12,invader[en].x,invader[en].y,18,18) AND invader[en].stat=0
invader[en].stat = 1
remshot = sh
score = score + 100
DEC sh
ENDIF
NEXT
IF remshot<>-1 THEN DIMDEL shots[],remshot
NEXT
FOREACH inva IN invader[]
IF BOXCOLL(shp.x,shp.y,30,30,inva.x,inva.y,18,18) AND inva.stat=0
youlose()
ENDIF
NEXT
FOREACH bul IN shots2[]
IF BOXCOLL(shp.x,shp.y,30,30,bul.x,bul.y,6,12)
IF shp.lives% = 0 THEN youlose()
shp.lives% = shp.lives% - 1
DELETE bul
ENDIF
NEXT
LOCAL none = 0
FOREACH inva IN invader[]
IF inva.stat = 0 THEN none = 1
NEXT
IF none = 0 THEN GOSUB main
// IF LEN(invader[])-1 = 0 THEN GOSUB main
ENDFUNCTION
FUNCTION youlose:
PRINT "*********** YOU lose ************",20,200
PRINT "******** PRESS A KEY RESTART *******",20,230
SHOWSCREEN
KEYWAIT
score = 0
shp.lives = 3
GOSUB main
END
ENDFUNCTION
FUNCTION createstars:xx
FOR n = 1 TO xx
LOCAL newone AS starfield
newone.x = RND(ssx-10)+10
newone.y = RND(ssy-10)+10
newone.s = RND(2)+1
DIMPUSH stars[],newone
NEXT
ENDFUNCTION
Just a small tip for naming lists of things in general.
When you define a type, name it in singular ex: "t_item"
When you define one item, name it "item" (singular)
When you define an array of items, name it "items" (plural)
This makes it slightly easier to remember the variable names.
Pseudocode: (I'm too rusty in GLBasic atm.)
TYPE t_item
...
ENDTYPE
GLOBAL items[] AS t_item
FOREACH item IN items[]
DELETE item
NEXT
For every while, for, type, function and so on, indent the code one more step to the right with spaces or tab
FUNCTION draw_screen:
LOCAL x, y // Only used inside this function
FOR x = 0 TO 50
FOR y = 0 TO 90
Draw(x,y)
NEXT
NEXT
ENDFUNCTION
Also, activate Project->Options "Explicit declarations" and make sure you declare all variables before usage. This will clear up much headache in the future :)
Thanks Moru
Type tip is a good 'un
I am bit sloppy with the other things but will try better in future ...
This is an older project that I decided to re-look at and make something from it... Just those weird issues are still there ....
Is my logic of
Loop
Checkkeys()
Checkhits()
Drawscreen()
Show screen
End loop
Okay or flawed?
No, that is fine but you need to clear up all the variables to make sure they are what you think they are. For example, if you don't declare a variable will it be local or global? The function that deletes the bullets, is it acting on an empty local variable or the global array of bullets? Is the draw function acting on a local variable instead of the global list of objects?
Just a few ideas of why explicit declaration is important even before you start on a project. This is why it is the default for new projects since a few years. Don't disable it even if you think you save time on not declaring the variables. It will bite your tail later :-)
If you are still stuck, PM me your source and I'll help!
Quote from: Darmakwolf on 2013-Oct-28
If you are still stuck, PM me your source and I'll help!
Hi Darmakwolf
Sent that to u last week I think my app timer has problems too
I did sort the firing issues and fixed that error but speed is still odd including aliens going faster in left dir to right??