BASIC

Author Topic: Achievements  (Read 2021 times)

MrTAToad

  • Guest
Achievements
« on: 2010-Jun-24 »
This is a little test program for an achievement system.  It could be regarded as inefficient, but when I post the code later, perhaps a better way could be found.

Anyway, see if you can find all the achievements :)  Using the cursor keys to move the block around

[attachment deleted by admin]

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10695
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Achievements
« Reply #1 on: 2010-Jun-24 »
It looks nice. A bit too fast fadeout here.

Offline backslider

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 892
    • View Profile
Re: Achievements
« Reply #2 on: 2010-Jun-24 »
Yes! Nice but really too fast :)
But it could be useful :)

MrTAToad

  • Guest
Re: Achievements
« Reply #3 on: 2010-Jun-24 »
Quote
A bit too fast fadeout here
Dont worry - you aren't missing much!

This is the code I am using :

Code: GLBasic [Select]
// --------------------------------- //
// Project: TestAchievements
// Start: Wednesday, June 23, 2010
// IDE Version: 8.006
TYPE tPlayerMovement
        x%
        y%
        distX%
        distY%
        move%[]
        achievementState%
        moveXDir%
        moveYDir%
ENDTYPE

TYPE tText
        text$
        x%
        y%
        alpha
ENDTYPE

PROTOTYPE achievements%:pm AS tPlayerMovement,text[] AS tText

TYPE tPlayer
        text[] AS tText
        pm AS tPlayerMovement
        achievementPtr AS achievements
ENDTYPE

LOCAL player AS tPlayer
LOCAL loop AS tText

player.pm.x%=100
player.pm.y%=100
player.pm.distX%=0
player.pm.distY%=0
DIM player.pm.move%[32]
player.pm.achievementState%=0
player.pm.moveXDir%=0
player.pm.moveYDir%=0
player.achievementPtr=achievement1

LIMITFPS -1
SETFONT 0

LOADSOUND "Media/app-29.wav",0,4

WHILE TRUE
        DRAWRECT player.pm.x%,player.pm.y%,16,16,RGB(255,0,0)

        FOREACH loop IN player.text[]
                ALPHAMODE loop.alpha
                PRINT loop.text$,loop.x%,loop.y%
                INC loop.alpha,0.005
                IF loop.alpha>-0.01
                        DELETE loop
                ENDIF
        NEXT

        SHOWSCREEN

        INC player.pm.x%,player.pm.moveXDir%
        INC player.pm.y%,player.pm.moveYDir%
        IF player.achievementPtr
                IF player.achievementPtr(player.pm,player.text[])
                ENDIF
        ENDIF
        player.pm.moveXDir%=((-1*KEY(203))+(1*KEY(205)))
        player.pm.moveYDir%=((-1*KEY(200))+(1*KEY(208)))
        INC player.pm.distX%,ABS(player.pm.moveXDir%)
        INC player.pm.distY%,ABS(player.pm.moveYDir%)
WEND

FUNCTION update%:pm AS tPlayerMovement,index%,text[] AS tText,extraText$
        pm.move[index%]=TRUE
        addAchievement(text[],extraText$)
        PLAYSOUND(0,0.0,1.0)
        RETURN TRUE
ENDFUNCTION

FUNCTION achievement1%:pm AS tPlayerMovement,text[] AS tText
        IF pm.move[0]=FALSE AND pm.moveXDir%<0 THEN RETURN update(pm,0,text[],"Moving Left")
        IF pm.move[1]=FALSE AND pm.moveXDir%>0 THEN RETURN update(pm,1,text[],"Moving Right")
        IF pm.move[2]=FALSE AND pm.moveYDir%<0 THEN RETURN update(pm,2,text[],"Moving Up")
        IF pm.move[3]=FALSE AND pm.moveYDir%>0 THEN RETURN update(pm,3,text[],"Moving Down")
        IF pm.move[4]=FALSE AND pm.distX%>=10 THEN RETURN update(pm,4,text[],"10 horizontal moves")
        IF pm.move[5]=FALSE AND pm.distX%>=100 THEN RETURN update(pm,5,text[],"100 horizontal moves")
        IF pm.move[6]=FALSE AND pm.distX%>=1000 THEN RETURN update(pm,6,text[],"1000 horizontal moves")
        IF pm.move[7]=FALSE AND pm.distX%>=10000 THEN RETURN update(pm,7,text[],"10000 horizontal moves")
        IF pm.move[8]=FALSE AND pm.distX%>=100000 THEN RETURN update(pm,8,text[],"100000 horizontal moves")
        IF pm.move[9]=FALSE AND pm.distX%>=1000000 THEN RETURN update(pm,9,text[],"100000 horizontal moves")
        IF pm.move[10]=FALSE AND pm.distY%>=10 THEN RETURN update(pm,10,text[],"10 vertical moves")
        IF pm.move[11]=FALSE AND pm.distY%>=100 THEN RETURN update(pm,11,text[],"100 vertical moves")
        IF pm.move[12]=FALSE AND pm.distY%>=1000 THEN RETURN update(pm,12,text[],"1000 vertical moves")
        IF pm.move[13]=FALSE AND pm.distY%>=10000 THEN RETURN update(pm,13,text[],"10000 vertical moves")
        IF pm.move[14]=FALSE AND pm.distY%>=100000 THEN RETURN update(pm,14,text[],"100000 vertical moves")
        IF pm.move[15]=FALSE AND pm.distY%>=1000000 THEN RETURN update(pm,15,text[],"100000 vertical moves")
        IF pm.move[16]=FALSE AND pm.x%<=0 AND pm.y%<=0 THEN RETURN update(pm,16,text[],"Top Left corner!")
        IF pm.move[17]=FALSE AND pm.x%>=640 AND pm.y%<=0 THEN RETURN update(pm,17,text[],"Top Right corner!")
        IF pm.move[18]=FALSE AND pm.x%<=0 AND pm.y%>=480 THEN RETURN update(pm,18,text[],"Bottom Left corner!")
        IF pm.move[19]=FALSE AND pm.x%>=640 AND pm.y%>=480 THEN RETURN update(pm,19,text[],"Bottom Right corner!")
        IF pm.move[20]=FALSE AND pm.moveXDir%<0 AND pm.moveYDir%<0 THEN RETURN update(pm,20,text[],"Diagonal 1")
        IF pm.move[21]=FALSE AND pm.moveXDir%>0 AND pm.moveYDir%>0 THEN RETURN update(pm,21,text[],"Diagonal 2")
        IF pm.move[22]=FALSE AND pm.x%=640/2 AND pm.y%=480/2 THEN RETURN update(pm,21,text[],"Centre of screen!")
        RETURN FALSE
ENDFUNCTION

FUNCTION addAchievement%:text[] AS tText,extra$
LOCAL t AS tText

        DIM text[0]
        t.text$="Congratulations!  Achievement awarded : "+extra$
        t.x%=0
        t.y%=0
        t.alpha=-1.0
        DIMPUSH text[],t
ENDFUNCTION

I had though of changing the function pointer for each achievement, but this would mean each achievement would be dependant on the previous one being completed, which isn't always the case.

The main thing is efficient code, with as little time as possible being taken to check for the achievements.

One thing I was thinking was having different pointers for each achievement that isn't dependant on any others (for example, corner, diagonal directional, and number of movements could each have their own pointer).

Once all achievement in a group has been completed, then the function pointer can be set to 0 so it wont need to be called, reducing the amount of checking needed to be done.

The other thing would be to use bitfields when an achievement has been completed
« Last Edit: 2010-Jun-24 by MrTAToad »