Omnimaga

Calculator Community => Other Calc-Related Projects and Ideas => TI-Nspire => Topic started by: annoyingcalc on September 03, 2012, 10:33:52 pm

Title: Duck hunt nspire port!
Post by: annoyingcalc on September 03, 2012, 10:33:52 pm
My first lua game! It is a port of duck hunt on the nes

(Im not even close to being done with this.)

Progress so far:

alpha v0.1
just the duck and background.

Controls
mouse to aim
click to shoot


Thanks
someone: program help

adriweb: helped me find an accident in code I made.






Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 04, 2012, 06:02:50 pm
New progress!
alpha v0.02
added duck falling if shot
added the annoying dog.


EDIT: for some reason it doesnt work very well on calc it was working great on my computer software though

Planned for next version
duck being shot sprite!

Planned for later:
better AI for duck
a limit for how long the duck is there untill it flys away!
title screen.
limited shots
Title: Re: Duck hunt nspire port!
Post by: Augs on September 04, 2012, 06:12:42 pm
Tell me when its playable, because all I see is a duck flying down with incredibly low framerate, and thats on the PC, donget me started with the on calc bit
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 04, 2012, 06:25:08 pm
Well idk why its different on the calc. And sorry about the speed lua will run at that speed >_>
Title: Re: Duck hunt nspire port!
Post by: someone on September 04, 2012, 08:07:00 pm
Hey annoyingcalc, here are some suggestions I have to make the code more legible & easier to modify that you might find useful:

Code: [Select]
-- IMAGES --
backSRC = ...
duckAliveSRC = ...
duckDeadSRC = ...
dogSRC = ...

img_dog = image.new(dogSRC)
img_duckAlive = image.new(duckAliveSRC)
img_duckDead = image.new(duckDeadSRC)
img_background = image.new(backSRC)

-- CONSTANTS --
duck = {
    h = image.height(img_duckAlive),    -- 30 px
    w = image.width(img_duckAlive)      -- 37 px
}
inc = 5        -- image movement increment
bg_gap = 50    -- background gap in coord X

function init()
    dx = 100
    dy = 50
    alive = 1
    x = 0
    y = 0
end

init()
function on.paint(gc)
    cursor.set("translation")
    cursor.show()

    -- Paint background
    gc:setColorRGB(0, 0, 0)
    gc:fillRect(0, 0, ww, wh)
   
    gc:drawImage(img_background, bg_gap, 0)
if alive==1 then
        gc:drawImage(img_duckAlive, dx, dy)
        gc:drawImage(img_duckAlive, dx, dy)
else
        if dy+duck.w <170 then
            gc:drawImage(img_duckDead, dx, dy)
        else
            gc:drawImage(img_dog, 150, 110)
        end
end
    AI()
end

function on.resize(width, height)
    ww = width
    wh = height
end

function on.mouseDown(x, y)
    if between(dx, x, dx+duck.w) and between(dy, y, dy+duck.h) then
        shot()
    else
        miss()
    end
end

function between(a, x, b)    -- Checks if "x" is between range [a,b]
    if a <= x and x <= b then
        return true
    else
        return false
    end
end

function AI()
    --place your Artificial Intelligence code here
if alive==1 then
if direction==1 then
dx = dx-inc
dy = dy-inc
        else
dx = dx+inc
dy = dy+inc
end
        if dx==bg_gap then
            direction=1
        end
        if dy >= wh then
            direction=0
        end
elseif dy+duck.w < 170 then
    dy = dy+inc
end
end

function shot()
    alive=0
end

function miss()
    -- Determine what happens if you missed a shot
end

function on.escapeKey()
    init()
    platform.window:invalidate()
end

I skipped the code with the image source since is to large & wasn't modified...
Here's what I did & why:

I see you made some comparisons with numbers 30 & 37, I assume this is the width & height of the image, that's why I set it to calculate it first & use them through a variable.

variable inc is the increment of how the duck moves. Is good to create a variable & change it at the top if you want it to modify later or in order to test different values.

bg_gap is the gap you left for the background. I don't know why 50, since 30 would be centered, so I leaved it there.

function init() was created in order to initialize everything, I used the key "esc" to call it. Useful to test everything from scratch w/o running or reopening the script. (if you want to use esc for something else, is easy to set it to any other key, though with a different function)

Created function "between" to make it easier to read when comparing where you shot (and renamed functioned used to a more informative one)


BTW, I see that you haven't checked the boundaries of the screen yet (and the way is currently determined is wrong). Maybe it would be better to determine where the duck is going to move next splitting the coordinates x & y.
Title: Re: Duck hunt nspire port!
Post by: DJ Omnimaga on September 04, 2012, 09:25:16 pm
Tell me when its playable, because all I see is a duck flying down with incredibly low framerate, and thats on the PC, donget me started with the on calc bit

Well at least give him a chance to start in Nspire programming and be more respectful for new coders. You should maybe suggest him optimizing tricks like "Someone" did, especially considering so far you didn't contribute anything for the Nspire, unlike annoyingcalc, who is trying to. EDIT2 woops edited wrong post >.<
Title: Re: Duck hunt nspire port!
Post by: Augs on September 05, 2012, 05:48:14 am
Tell me when its playable, because all I see is a duck flying down with incredibly low framerate, and thats on the PC, donget me started with the on calc bit

Well at least give him a chance to start in Nspire programming and be more respectful for new coders. You should maybe suggest him optimizing tricks like "Someone" did, especially considering so far you didn't contribute anything for the Nspire, unlike annoyingcalc, who is trying to.

I was just saying that he should not make a new "release" for every line of code he types. I'm all for the project. I can't be much help since I am also new to this.

I will have you know that I am currently developing a 2 player RPG.
Title: Re: Duck hunt nspire port!
Post by: Adriweb on September 05, 2012, 06:44:35 am
Here is a cleaner code.
Also, the reason(s) why it's not working the same on-calc is becuase the computer forces the refresh of the screen, but you have to call it yourself by calling [lua]platform.window:invalidate[/lua]
Also, since you want the game to be always running (the AI), call it in a timer. (See code)

I also made the duck images transparent (thanks to http://bwns.be/jim/sprite.html )

Quick note for the optimizations :   when you see stuff like    "a = (b>1) and 3 or 2" it's the same as : "if b>1 then a = 3 else a = 2 end"

And ... I recoded the AI (quickly)

Cleaner Code with properindentations, separations of events and functions, init code at the end.
Code: [Select]
platform.apilevel = "1.0"

-----------------------
------ Constants ------
-----------------------

inc = 5 -- image movement increment
bg_gap = 50 -- background gap in coord-- X


-----------------------
------   Events  ------
-----------------------

function on.paint(gc)
    -- Paint background
    gc:setColorRGB(0, 0, 0)
    gc:fillRect(0, 0, ww, wh)

    gc:drawImage(img_background, bg_gap, 0)
    if alive then
        gc:drawImage(img_duckAlive, dx, dy)
    else
        if dy + duck.h < 194 then
            gc:drawImage(img_duckDead, dx, dy)
        else
            gc:drawImage(img_dog, dx, dy-duck.h)
        end
    end

    gc:setColorRGB(255, 255, 255)
    gc:drawString(msg, 0, 0, "top")
end

function on.resize(width, height)
    cursor.set("translation")
    cursor.show()
    ww, wh = width, height
    platform.window:invalidate()
end

function on.mouseDown(x, y)
    if between(dx, x, dx + duck.w) and between(dy, y, dy + duck.h) then
        shot()
    else
        miss()
    end
    platform.window:invalidate()
end

function on.escapeKey()
    init()
    platform.window:invalidate()
end

function on.timer()
    AI()
    platform.window:invalidate()
end

-----------------------
------ Functions ------
-----------------------

function init()
    dx = 100
    dy = 50
    dirX = 1
    dirY = 1
    alive = true
    x = 0
    y = 0
    msg = ""
end

function between(a, x, b) -- Checks if "x" is between range [a,b]
    return (a <= x) and (x <= b)
end

function AI()
    if alive then
        dx = dx + dirX*inc
        dy = dy + dirY*inc
    elseif dy + duck.h < 194 then
        dy = dy + inc
    end
    
    if dx <= bg_gap then dirX = 1 end
    if dx >= ww-duck.w then dirX = -1 end
    if dy <= 0 then dirY = 1 end
    if dy >= 170-duck.h then dirY = -1 end
end

function shot()
    alive = false
    msg = "Shot !"
end

function miss()
    -- Determine what happens if you missed a shot
    msg = "Missed !"
end


-----------------------
------   Init:   ------
-----------------------

-- images --

img_dog = image.new(dogSRC)
img_duckAlive = image.new(duckAliveSRC)
img_duckDead = image.new(duckDeadSRC)
img_background = image.new(backSRC)

duck = {
    h = image.height(img_duckAlive), -- 30 px
    w = image.width(img_duckAlive) -- 37 px
}

init()
timer.start(0.05)
Title: Re: Duck hunt nspire port!
Post by: Hayleia on September 05, 2012, 12:04:03 pm
I was just saying that he should not make a new "release" for every line of code he types.
What is the problem with this ? You don't have to download every release he makes. If he updates regularly, we know he didn't give up and we can easily follow his progress. And this allows people like Adriweb and Someone to help him on an updated code.
Title: Re: Duck hunt nspire port!
Post by: DJ Omnimaga on September 05, 2012, 01:28:15 pm
Yeah I agree with that. Of course if the first post would have said this is the best project in history of Nspire coding and the best game ever and all there was was the current progress then I wouldn't be fine with it due to being very misleading, but otherwise I think it's OK since each post states its status and upcoming updates. Just making sure that people remain respectful and polite when commenting on projects.  A few years ago before the post rating system was instated, any project comment that didn't contain anything constructive was ban-worthy material. On other sites at the time, what usually happened was the project author just plain quitting entirely.
Title: Re: Duck hunt nspire port!
Post by: Augs on September 05, 2012, 01:32:38 pm
Sorry folks. I didn't mean to cause a stir.
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 05, 2012, 03:40:51 pm
Also, the reason(s) why it's not working the same on-calc is becuase the computer forces the refresh of the screen, but you have to call it yourself by calling [lua]platform.window:invalidate[/lua]
Ah, I thought I had this in code.
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 13, 2012, 08:19:38 pm
Hm im trying to make all my sprites transparent but my browser freezes when I paste the sprite
Title: Re: Duck hunt nspire port!
Post by: blfngl on September 13, 2012, 08:33:46 pm
Honestly this is going really good so far! Keep it up, can't wait until a calc optimized version is released 7:^)
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 29, 2012, 09:35:28 pm
Hm, I have a bunch of new code to add ( all coded during school XD )
but I need someone to make the sprites transparent and post the file here
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on September 29, 2012, 11:05:36 pm
Never mind my previous post I fixed the problem!

Here is v4

added a time limit
added fly away
added fly away animation
added level time

Todo:
add main menu
optimize
add more dog and bird animations
more ducks
Maybe even dog mode
Title: Re: Duck hunt nspire port!
Post by: Spenceboy98 on January 04, 2013, 05:06:31 pm
Here is a cleaner code.
Also, the reason(s) why it's not working the same on-calc is becuase the computer forces the refresh of the screen, but you have to call it yourself by calling [lua]platform.window:invalidate[/lua]
Also, since you want the game to be always running (the AI), call it in a timer. (See code)

I also made the duck images transparent (thanks to http://bwns.be/jim/sprite.html )

Quick note for the optimizations :   when you see stuff like    "a = (b>1) and 3 or 2" it's the same as : "if b>1 then a = 3 else a = 2 end"

And ... I recoded the AI (quickly)

Cleaner Code with properindentations, separations of events and functions, init code at the end.
Code: [Select]
platform.apilevel = "1.0"

-----------------------
------ Constants ------
-----------------------

inc = 5 -- image movement increment
bg_gap = 50 -- background gap in coord-- X


-----------------------
------   Events  ------
-----------------------

function on.paint(gc)
    -- Paint background
    gc:setColorRGB(0, 0, 0)
    gc:fillRect(0, 0, ww, wh)

    gc:drawImage(img_background, bg_gap, 0)
    if alive then
        gc:drawImage(img_duckAlive, dx, dy)
    else
        if dy + duck.h < 194 then
            gc:drawImage(img_duckDead, dx, dy)
        else
            gc:drawImage(img_dog, dx, dy-duck.h)
        end
    end

    gc:setColorRGB(255, 255, 255)
    gc:drawString(msg, 0, 0, "top")
end

function on.resize(width, height)
    cursor.set("translation")
    cursor.show()
    ww, wh = width, height
    platform.window:invalidate()
end

function on.mouseDown(x, y)
    if between(dx, x, dx + duck.w) and between(dy, y, dy + duck.h) then
        shot()
    else
        miss()
    end
    platform.window:invalidate()
end

function on.escapeKey()
    init()
    platform.window:invalidate()
end

function on.timer()
    AI()
    platform.window:invalidate()
end

-----------------------
------ Functions ------
-----------------------

function init()
    dx = 100
    dy = 50
    dirX = 1
    dirY = 1
    alive = true
    x = 0
    y = 0
    msg = ""
end

function between(a, x, b) -- Checks if "x" is between range [a,b]
    return (a <= x) and (x <= b)
end

function AI()
    if alive then
        dx = dx + dirX*inc
        dy = dy + dirY*inc
    elseif dy + duck.h < 194 then
        dy = dy + inc
    end
   
    if dx <= bg_gap then dirX = 1 end
    if dx >= ww-duck.w then dirX = -1 end
    if dy <= 0 then dirY = 1 end
    if dy >= 170-duck.h then dirY = -1 end
end

function shot()
    alive = false
    msg = "Shot !"
end

function miss()
    -- Determine what happens if you missed a shot
    msg = "Missed !"
end


-----------------------
------   Init:   ------
-----------------------

-- images --

img_dog = image.new(dogSRC)
img_duckAlive = image.new(duckAliveSRC)
img_duckDead = image.new(duckDeadSRC)
img_background = image.new(backSRC)

duck = {
    h = image.height(img_duckAlive), -- 30 px
    w = image.width(img_duckAlive) -- 37 px
}

init()
timer.start(0.05)

Is this the most recent code?
Title: Re: Duck hunt nspire port!
Post by: annoyingcalc on January 05, 2013, 01:09:26 pm
No, here is the most recent code
Code: [Select]
platform.apilevel = "1.0"

-----------------------
------ Constants ------
-----------------------

inc = 5 -- image movement increment
bg_gap = 50 -- background gap in coord-- X
sec = 0
seclim = 32


-----------------------
------   Events  ------
-----------------------

function on.paint(gc)
    -- Paint background
    gc:setColorRGB(0, 0, 0)
    gc:fillRect(0, 0, ww, wh)

    gc:drawImage(img_background, bg_gap, 0)
    if alive == 1 then
        gc:drawImage(img_duckAlive, dx, dy)
    else
        if dy + duck.h < 194 and alive ~= 2 then
            gc:drawImage(img_duckDead, dx, dy)
        else
if alive ~= 2 then
            gc:drawImage(img_dog, dx, dy-duck.h)
else
gc:drawImage(img_duckAlive,dx,dy)
AI()
end
        end
    end
if alive == 2 then
gc:setColorRGB(0,0,0)
gc:fillRect(100,50,65,25)
gc:setColorRGB(255,255,255)
gc:drawString("Fly Away",100,70)
    end
gc:setColorRGB(255, 255, 255)
    gc:drawString(msg, 0, 0, "top")
end

function on.resize(width, height)
    cursor.set("crosshair")
    cursor.show()
    ww, wh = width, height
    platform.window:invalidate()
end

function on.mouseDown(x, y)
    if between(dx, x, dx + duck.w) and between(dy, y, dy + duck.h) then
        shot()
    else
        miss()
    end
    platform.window:invalidate()
end

function on.escapeKey()
    init()
    platform.window:invalidate()
end

function on.timer()
sec=sec+0.5
    AI()
    platform.window:invalidate()
if sec >= seclim then
alive = 2
platform.window:invalidate()
end
end

-----------------------
------ Functions ------
-----------------------

function init()
    dx = 100
    dy = 50
    dirX = 1
    dirY = 1
    alive = 1
    x = 0
    y = 0
    msg = ""
sec = 0
end
function between(a, x, b) -- Checks if "x" is between range [a,b]
    return (a <= x) and (x <= b)
end

function AI()
    if alive == 1 then
        dx = dx + dirX*inc
        dy = dy + dirY*inc
    elseif dy + duck.h < 194 then
        dy = dy + inc
    end
    if alive == 2 then dx = dx - dirY*inc end
    if dx <= bg_gap then dirX = 1 end
    if dx >= ww-duck.w then dirX = -1 end
    if dy <= 0 then dirY = 1 end
    if dy >= 170-duck.h then dirY = -1 end
end

function shot()
    alive = 0
    msg = "Shot !"
seclim = seclim - 2
end

function miss()
    -- Determine what happens if you missed a shot
    msg = "Missed !"
end


-----------------------
------   Init:   ------
-----------------------

-- images --

img_dog = image.new(dogSRC)
img_duckAlive = image.new(duckAliveSRC)
img_duckDead = image.new(duckDeadSRC)
img_background = image.new(backSRC)

duck = {
    h = image.height(img_duckAlive), -- 30 px
    w = image.width(img_duckAlive) -- 37 px
}

init()
timer.start(0.05)
Title: Re: Re: Duck hunt nspire port!
Post by: Nick on January 05, 2013, 01:21:56 pm
Another nice improvement might be the use of a class for the duck (and other). That'll make it much more easy do code, and a lot cleaner.