Omnimaga
Calculator Community => Other Calc-Related Projects and Ideas => TI-Nspire => Topic started 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.
-
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
-
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 idk why its different on the calc. And sorry about the speed lua will run at that speed >_>
-
Hey annoyingcalc, here are some suggestions I have to make the code more legible & easier to modify that you might find useful:
-- 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.
-
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 >.<
-
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.
-
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.
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)
-
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.
-
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.
-
Sorry folks. I didn't mean to cause a stir.
-
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.
-
Hm im trying to make all my sprites transparent but my browser freezes when I paste the sprite
-
Honestly this is going really good so far! Keep it up, can't wait until a calc optimized version is released 7:^)
-
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
-
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
-
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.
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?
-
No, here is the most recent code
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)
-
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.