I have recently been familiar with lua in LOVE 2D and watched some tutorials and now am trying to make a simple game. The game will feature a character who can run and when pressed 'space', attack(strike with his sword). When pressed 'space', it should go through all the frames/sprites of attacking animation. But the character is not going through all the frames and the interval between them seems really fast even though I kept it minimum.
This is the code I am using to account for the key pressing.
self.animations = {
['idle'] = Animation{
frames = {
self.frames[1]
},
interval = 1
},
['attack'] = Animation{
frames = {
self.frames[1], self.frames[2], self.frames[3], self.frames[4], self.frames[5], self.frames[6], self.frames[3]
},
interval = 0.25
}
}
self.animation = self.animations['idle']
self.currentFrame = self.animation:getCurrentFrame()
self.behaviors = {
['idle'] = function(dt)
if love.keyboard.wasPressed('space') then
self.dy = 0
self.state = 'attack'
self.animation = self.animations['attack']
elseif love.keyboard.wasPressed('up') then
self.dy = -MOVE_DIST
elseif love.keyboard.wasPressed('down') then
self.dy = MOVE_DIST
else
self.dy = 0
end
end,
['attack'] = function(dt)
self.animation = self.animations['attack']
if love.keyboard.wasPressed('up') then
self.dy = -MOVE_DIST
elseif love.keyboard.wasPressed('down') then
self.dy = MOVE_DIST
else
self.dy = 0
self.state = 'idle'
self.animation = self.animations['idle']
end
end
This is my animation class that's responsible for transition effects
Animation = Class{}
function Animation:init(params)
--self.texture = params.texture
self.frames = params.frames
self.interval = params.interval or 0.05
self.timer = 0
self.currentFrame = 1
end
function Animation:getCurrentFrame()
return self.frames[self.currentFrame]
end
function Animation:restart()
self.timer = 0
self.currentFrame = 1
end
function Animation:update(dt)
self.timer = self.timer + dt
if #self.frames == 1 then
return self.currentFrame
else
while self.timer > self.interval do
self.timer = self.timer - self.interval
self.currentFrame = (self.currentFrame + 1) % (#self.frames + 1)
if self.currentFrame == 0 then
self.currentFrame = 1
end
end
end
end
Please help. I hope I asked the question correctly. Thanks in advance.
Don't really know how you deal with the state in the key pressing code but this could be part of the issue too.
Anyway, your Animation:update looks very weird to me and I really think this is the center of the problem. There is a simple function that you could use instead and it should work perfectly (if you have any question about it feel free to ask).
If your not really comfortable with a debugger you could use love.graphics.print to print some value to the screen (like self.currentFrame or self.timer in that case) to see what's going on with those value in real time.
function Animation:update(dt)
self.timer = self.timer + dt/self.interval
if self.timer >= #self.frames then
self.timer = 0
end
self.currentFrame = Math.floor(self.timer)+1
end
Also note that "Math.floor(self.timer)+1" cannot be replaced by "Math.ceil(self.timer)" because it will return 0 if self.timer == 0 (and lua's array starts at one)
Edit:
It could probably come from here:
['attack'] = function(dt)
self.animation = self.animations['attack']
if love.keyboard.wasPressed('up') then
self.dy = -MOVE_DIST
elseif love.keyboard.wasPressed('down') then
self.dy = MOVE_DIST
else
self.dy = 0
self.state = 'idle'
self.animation = self.animations['idle']
end
end
I don't know how you deal with your inputs since 'love.keyboard.wasPressed' if not a love function but if 'up' and 'down' where not pressed the last frame, the state will go back to 'idle' and the animation to animations['idle']
Without more code I cannot do much more for you.
Related
Objective: to change color intensity of pixels
Code:
using Images, ImageView;
function updateColors(path::String)
if isfile(path)
img = load(path);
chnlView = channelview(img);
chnlView[chnlView .> 0.7] = 0.9;
imshow(img);
else
info("Error: Image Not Found!");
end
end
#By Prof.Bogumił Kamiński
function quit()
print("Press q to quit!");
while true
opt = getChar();
if opt == 'q'
break
else
continue
end
end
end
#By Prof.Bogumił Kamiński
function getChar()
ret = ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, true)
ret == 0 || error("unable to switch to raw mode")
c = read(stdin, Char)
ccall(:jl_tty_set_mode, Int32, (Ptr{Cvoid},Int32), stdin.handle, false)
c
end
updateColors("/opt/julia/pictures/test.jpg");
quit();
Error:
no method matching setindexshape(::Float64, ::Int64)
Please help me in resolving the issue!
You should broadcast the assignment operation like this:
chnlView[chnlView .> 0.7] .= 0.9
Currently I have 6 images layered over top of each other, each with their own corresponding walk animation frame. Each time you walk the Visible property changes and allows the next animation frame to be seen.
The only problem is the bloody flickering when it is passing through any type of object be it, picturebox, form, command button, etc....
After a tiresome day of research I just can't come up with a solution to fix this.
a little snippet of my code if anyone want's to see:
Select Case CharFrame
Case 1
Avatar(0).Visible = True
Avatar(1).Visible = False
Avatar(2).Visible = False
CharFrame = CharFrame + 1
Case 2
Avatar(0).Visible = False
Avatar(1).Visible = True
Avatar(2).Visible = False
CharFrame = CharFrame + 1
Case 3
Avatar(0).Visible = False
Avatar(1).Visible = False
Avatar(2).Visible = True
CharFrame = 1
End Select
Sleep (Timer)
Avatar(0).Top = Avatar(0).Top + moveY
Avatar(1).Top = Avatar(1).Top + moveY
Avatar(2).Top = Avatar(2).Top + moveY
Avatar(3).Top = Avatar(0).Top
Avatar(4).Top = Avatar(1).Top
Avatar(5).Top = Avatar(2).Top
Avatar(6).Top = Avatar(0).Top
Avatar(7).Top = Avatar(1).Top
Avatar(8).Top = Avatar(2).Top
Avatar(9).Top = Avatar(0).Top
Avatar(10).Top = Avatar(1).Top
Avatar(11).Top = Avatar(2).Top
Loop
Avatar(0).Visible = True
Avatar(1).Visible = False
Avatar(2).Visible = False
Found this with Google:
Private Declare Function LockWindowUpdate Lib "USER32" (ByVal hwndLock As Long) As Long
When you like to stop window updating:
LockWindowUpdate <yourform>.hWnd
If you like to continue
LockWindowUpdate False
Found this, did not try it.
Anyone can help me. I create some sprite images for a jump animate. But it cannot animated as I want, it only showing the first frame ( I set it for 7 jump frame). Here is my corona code.
function playerJump( event )
if event.phase == "ended" then
if doubleJump == false then
player:setLinearVelocity( 0, 0 )
player:applyForce(0,-30, player.x, player.y)
player:setSequence("jump")
jumpChannel = audio.play(jumpSound)
end
if singleJump == false then singleJump = true
else doubleJump = true end
end
return true
end
Then below that function, I generate the sprite
local options =
{
width = 60, height = 100,
numFrames = 33,
sheetContentWidth = 1980,
sheetContentHeight = 100
}
playerSheet = graphics.newImageSheet( "images/playerSprite.png", options)
playerSprite = {
{name="run", frames = {1,3,5,7,9,11,13,15,17,19,21,23,25}, time = 700, loopCount = 0 },
{name="jump", frames = {27,28,29,30,31,32,33}, time = 1000, loopCount = 1 },
}
--Add the jump listener
Runtime:addEventListener("touch", playerJump)
Thankyou very much
Regards
function playerJump( event )
if event.phase == "ended" then
if doubleJump == false then
player:setLinearVelocity( 0, 0 )
player:applyForce(0,-30, player.x, player.y)
player:setSequence("jump")
player:play() --- You have forgot to add this line.
jumpChannel = audio.play(jumpSound)
end
if singleJump == false then singleJump = true
else doubleJump = true end
end
return true
end
I created NPCs that move that direction you're standing at the moment. If they touch something, they never will move again. I don't have a clue and already wasted like 6 hours searching the fault.
That is my Move-Method:
Overrides Sub Move()
Dim actorPosition As Vector2
Dim spieler As Actor
For Each obj As Actor In Actor.ActorList
If TypeOf obj Is Actor And obj.Alive And obj.ObjektTyp = "A"c Then
actorPosition = obj.position
spieler = obj
End If
Next
Dim difPos As Vector2 = position - actorPosition
normaldifpos = difPos
normaldifpos.Normalize()
If lastTimeAttack + intervallBetweenAttack1 < Game1.Game1Time Then
If difPos.Length < range Then
Select Case ObjektTyp
Case "Z"c
spieler.leben -= stärke
Case "H"c
For Each obj As Objekt In ObjList
If TypeOf obj Is Spells Then
If obj.ObjektTyp = "Z"c And obj.Alive = False Then
obj.position = position
obj.richtung = -normaldifpos
obj.senderE = Me
obj.stärke = stärke
obj.Alive = True
Exit For
End If
End If
Next
End Select
lastTimeAttack = Game1.Game1Time
End If
End If
If difPos.Length() < agroRange Then
If spieler IsNot Nothing And Not collide((normaldifpos + New Vector2(-4, -4) * speed)) Then
position = position - normaldifpos * speed
Else
End If
End If
End Sub
And this my collide method:
Public Overridable Function collide(vek As Vector2) As Boolean
Dim extrahitbox As Rectangle
extrahitbox = Hitbox
extrahitbox.X += vek.X
extrahitbox.Y += vek.Y
For Each obj As Objekt In Objekt.ObjList
If TypeOf obj Is Spells Or TypeOf obj Is Key Or TypeOf obj Is PowerUP Or TypeOf obj Is Coin Then
Else
If extrahitbox.Intersects(obj.Hitbox) Then
Return True
End If
End If
Next
For Each Act As Actor In Actor.ActorList
If Act IsNot Me Then
If extrahitbox.Intersects(Act.Hitbox) Then
Return True
Else
End If
End If
Next
If extrahitbox.X < 0 Then
Return True
ElseIf extrahitbox.Right > 1280 Then
Return True
ElseIf extrahitbox.Top < 0 Then
Return True
ElseIf extrahitbox.Bottom > 720 Then
Return True
End If
End Function
I would appreciate help!
From your example it looks object stuck because once when it collide with other object you are not doing any update to position. After determing collision you have to calculate how deep object is inside other object and move it back to previous position.
One way is after you determinate collision you simply negate velocity.
object.Position -= object.Velocity
object.Velocity = new vector2(0,0)
Other way is more accurate as velocity remain same and if your origin is on top-left position. It collision happened, it will position your object right next to other object depend from where collision happened.
If obj.Intersect(otherObj) Then
Dim newPos as new vector2d = obj.Position
if (obj.velocity.x>0) then newPos.x = otherObj.Left - obj.width
if (obj.velocity.x<0) then newPos.x = otherObj.right
obj.Position = newPos
End If
So basicly goes like this
put position to temp varialbe
check collision
if collision happened set original to temp
draw
I am new to ActionScript-3 and I am attempting to make a game to learn more.
For every picture that is displayed I want there to be 4 choices (buttons) and only one of them to be the correct one. But how can I make it so that the text from the buttons will be random.
As you can see I've made it so the 4th button is always the correct answer. I don't want to make all this thing for every picture that is displayed...to much pointless code.
Can anybody help me? If you need extra information I will gladly provide it.
var k:int;
for(k=1;k<=3;k++)
{
GAME.variante.buttonMode=true;
GAME.variante.addEventListener(MouseEvent.MOUSE_OVER,mouse_over_variante);
GAME.variante.addEventListener(MouseEvent.MOUSE_OUT,mouse_out_variante);
GAME.variante.varianta_corecta.addEventListener(MouseEvent.CLICK,variante);
GAME.variante.varianta_gresita1.addEventListener(MouseEvent.CLICK,variante_gresiteunu);
GAME.variante.varianta_gresita2.addEventListener(MouseEvent.CLICK,variante_gresitedoi);
GAME.variante.varianta_gresita3.addEventListener(MouseEvent.CLICK,variante_gresitetrei);
GAME.varianta1.text = "Cameleon";
GAME.varianta2.text = "Snake";
GAME.varianta3.text = "Frog";
GAME.varianta4.text = "Snail";
function variante_gresiteunu(e:MouseEvent){
if (varianta_gresita_apasata1 == 1){
totalScore -= score_variante_gresite;
GAME.text1.text = totalScore;
varianta_gresita_apasata1 = 2;
}
}
function variante_gresitedoi(e:MouseEvent){
if (varianta_gresita_apasata2 == 1){
totalScore -= score_variante_gresite;
GAME.text1.text = totalScore;
varianta_gresita_apasata2 = 2;
}
}
function variante_gresitetrei(e:MouseEvent){
if (varianta_gresita_apasata3 == 1){
totalScore -= score_variante_gresite;
GAME.text1.text = totalScore;
varianta_gresita_apasata3 = 2;
}
}
}
GAME.extra_points.visible = false;
function variante (e:MouseEvent) {
if (GAME.stichere.sticker1.currentFrame == (1)){
GAME.extra_points.visible = true;
GAME.extra_points.plus_ten1.gotoAndPlay(1);
}
//go to great job screen
GAME.greatJob.stars.gotoAndPlay(1);
GAME.greatJob.visible = true;
}
function mouse_over_variante (e:MouseEvent) {
trace(e.target.name);
e.target.gotoAndPlay(1);
}
function mouse_out_variante (e:MouseEvent) {
e.target.gotoAndStop(1);
}
You like to have 4 images and they will be tested right?
The text below the images will be randomness. I saw your code and I
confess I was confused. I made a different one.
I undestand that this code is a little diferent of what you ask, but i think it will > give you some new ideas and help you on your app...
//start button added on the sceen named f3toc. I give a function name for him f3roll.
f3toc.addEventListener(MouseEvent.CLICK,f3roll);
function f3roll(e:MouseEvent):void{
//creating variables for the picture.
var bola:Number
var quadrado:Number
var pentagono:Number
//Here is just a randomization code, you can change it to the what you want to use after the =
bola = Math.ceil(Math.random() * 10);
pentagono = Math.ceil(Math.random() * 10);
f3res1_txt.text = String (bola + 8 + 8);
f3res2_txt.text = String(bola - 1 + bola);
f3res3_txt.text = String (pentagono + 10 - bola);
//converting number to string so we can put tem into the text fields.
var pentagonotring:String = pentagono.toString();
var bolastring:String = bola.toString();
//function to check wen the name is correct. each wrong do nothing and every correct add 1 to a variable, in the end wen this variable reach 3 it does something.
f3check_bnt.addEventListener (MouseEvent.CLICK, f3check);
function f3check (e:MouseEvent):void{
if (f3inp2_txt.text == pentagonotring){
f3ver_ext2.text = "Correct"
} else {f3ver_ext2.text = "Wrong";}
if (f3inp1_txt.text == bolastring){
f3ver_ext1.text = "Correct"
}else {f3ver_ext1.text = "Wrong";}
// function to check wen the variable pass reach 3
pass = 0;
if (f3ver_ext1.text == "Correct"){
pass++
}
if (f3ver_ext2.text == "Correct"){
pass++
if (pass == 3){
nextFrame();
}}}}