Thanks for that link Peach, I have reprogrammed my game using that method of external modules. Unfortunately the error must not be related to that because I have ended up with the exact same error :(.
I will elaborate more this time. I don’t think it is because multiple collision per file are not allowed, because I tested using 2 collisions in a file and it worked fine, something else is going on here.
In main I wish for the following collision handling functions to be used: (I will post my entire main file as I suspect there is something wrong in there somewhere).
-- Shooter Engine 1.0.
-- If an object is not defined when it is called, a nil error will occur.
-- Don't want anything global - creates scope issues.
-- Touch listeners and collision listeners (I think) get removed auto, only enterFrames don't.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Private part of module.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Use this to access other modules.
local Player = require("Player");
local Enemy = require("Enemy");
local Pow = require("Pow");
-- Local Constants
local \_H = display.contentHeight;
local \_W = display.contentWidth;
-- Local Variables
local xCoord; -- Used to position explosion.
local yCoord; -- Used to position explosion.
local explosion; -- Solve timer parameter issue.
local sheetExplosion; -- Solve timer parameter issue.
-- Enable Physics Engine.
physics = require("physics");
physics.start();
physics.setGravity(0,0); -- Eliminate gravity.
-- Background music to be loaded.
local soundtrack = audio.loadStream("Media/Sound/Background\_Music.aiff");
-- Background images to be loaded.
-- Used to remove bullets off stage.
local ceiling = display.newRect(0,0,\_W,1); -- position top left, \_W is display width 20 is height.
ceiling:setReferencePoint(display.CenterReferencePoint); -- center ref pt is important with physics.
ceiling.x = \_W/2; ceiling.y = -30;
ceiling.isHitTestable = true;
ceiling.isVisible = false;
ceiling.myName = "ceiling";
physics.addBody(ceiling, { isSensor = true });
-- Play music when app is launched.
audio.play(soundtrack, {loops=-1}); -- Loops infinite times (-1).
audio.setVolume(1.0, { channel=1 } ); -- Use to adjust background sound volume.
-- Load background image here.
-- Instantiate Player.
local hero = Player.new(); -- Call new function in player.lua.
Player.start\_Playing(); -- Call start\_Playing function in player.lua
Enemy.new(100,0,0,100);
Enemy.new(300,0,0,100);
Pow.new();
-- Instantiate Enemies.
local function explody()
print( "in explody" );
explosion:removeSelf();
explosion = nil;
-- These two lines free texture from memory.
sheetExplosion:dispose();
sheetExplosion = nil;
end
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Public part of module.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Put collision stuff here.
function onBulletCollision( self, event )
if(event.phase == "began") then
-- Use an elseif here, so it hits the enemy OR it goes off screen for a second and is removed. Don't want to be able to shoot enemies off screen.
-- Could use another if here if have different types of enemies.
-- To free up memory. Remove bullet when off screen.
if(event.other.myName == "met") then
print( self.myName .. ": collision began with " .. event.other.myName ); -- Collision testing ok. (Remove on release).
self:removeSelf(); -- Remove self (bullet).
self = nil; -- Extra cautious.
xCoord = event.other.x; yCoord = event.other.y; -- Get coordinates of meteor.
event.other:removeSelf(); -- Remove the meteor from memory.
event.other = nil; -- Removing this allows us to go into other if statement.
print( xCoord .. " " .. yCoord ); -- Check ok. (Remove on release).
-- Once enemy is gone, create explosion at coordinate. This happens for every enemy.
require "sprite";
sheetExplosion = sprite.newSpriteSheet( "Media/Images/explosionSheet.png", 99,119);
local spriteSetExplosion = sprite.newSpriteSet(sheetExplosion, 1, 3); -- three frames.
sprite.add( spriteSetExplosion, "expl", 1, 3, 100,0); -- play 3 frames once. 0.1s animation.
explosion = sprite.newSprite( spriteSetExplosion ); -- Load explosion image.
explosion.x = xCoord; explosion.y = yCoord; -- Position at the (x,y) coordinates of meteor.
explosion:prepare("expl"); -- Load animation.
explosion:play(); -- Play animation.
timer.performWithDelay(100, explody, 1); -- Give object time to animate. Pass newly created explosion object to explody function.
elseif(event.other.myName == "ceiling") then
print( self.myName .. ": collision began with " .. event.other.myName ); -- Collision testing ok.
self:removeSelf();
self = nil;
end
end
end
function onPlaneCollision( self, event )
if(event.phase == "began") then
if(event.other.myName == "met") then
print( self.myName .. ": collision began with " .. event.other.myName );
end
end
end
function speedCollision( self, event )
if(event.phase == "began") then
if(event.other.myName == "Hero") then
print( self.myName .. ": collision began with " .. event.other.myName );
end
end
end
my onBulletCollision( self, event ) code executes perfectly. the problem arises with the other two functions, onPlaneCollision and speedCollision. When a collision happens no code is executed for either of the two. If I put the two functions inside any other file - Pow.lua for example, it works fine. Shown below:
-- Power up functionality code.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Private part of module.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Local Constants.
local \_H = display.contentHeight;
local \_W = display.contentWidth;
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
-- Public part of module.
-- \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
local Pow = {};
-- Create a power up object.
Pow.new = function()
require "sprite";
local sheetSpeed = sprite.newSpriteSheet( "Media/Images/speedSheet.png", 59,66);
local spriteSetSpeed = sprite.newSpriteSet(sheetSpeed, 1, 2); -- two frames.
sprite.add( spriteSetSpeed, "flash", 1, 2, 200, 0 ); -- play 2 frames every 500 ms
local speedUp = sprite.newSprite( spriteSetSpeed );
speedUp.myName = "speed";
speedUp.x = 400; speedUp.y = 0;
physics.addBody(speedUp, { isSensor = true });
speedUp:prepare("flash");
speedUp:play();
speedUp:setLinearVelocity(0,100);
speedUp.collision = speedCollision
speedUp:addEventListener( "collision", speedUp );
return speedUp;
end
function onPlaneCollision( self, event )
if(event.phase == "began") then
if(event.other.myName == "met") then
print( self.myName .. ": collision began with " .. event.other.myName );
end
end
end
function speedCollision( self, event )
if(event.phase == "began") then
if(event.other.myName == "Hero") then
print( self.myName .. ": collision began with " .. event.other.myName );
end
end
end
return Pow;
I am doing my collisions the exact same way as my onBulletCollision code, I’ll show direct comparisons here: (they both appear in the same file).
function fire\_button:touch(event)
if(event.phase == "began") then
image\_Select({type = "fire\_btn\_start"});
audio.play(bullet\_sound);
local player\_shot = display.newImage("Media/Images/Player\_Bullet.png");
player\_shot:setReferencePoint(display.CenterReferencePoint);
player\_shot.x = plane.x; player\_shot.y = plane.y-40;
player\_shot.myName = "bullet";
physics.addBody(player\_shot, { isSensor = true });
player\_shot:setLinearVelocity(0,bullet\_speed);
-- Every player bullet gets assigned it's own collision label.
player\_shot.collision = onBulletCollision -- Can call onBulletCollision in main directly as it is public.
player\_shot:addEventListener( "collision", player\_shot );
end
if(event.phase == "ended") then
image\_Select({type = "fire\_btn\_end"});
end
return true;
end
fire\_button:addEventListener("touch", fire\_button);
Player.new = function()
require "sprite";
local sheetPlayer = sprite.newSpriteSheet( "Media/Images/spriteSheet1.png", 123,120);
local spriteSetPlayer = sprite.newSpriteSet(sheetPlayer, 1, 2); -- two frames.
sprite.add( spriteSetPlayer, "flying", 1, 2, 200, 0 ); -- play 2 frames every 1000 ms
plane = sprite.newSprite( spriteSetPlayer ); -- Uses local plane declared up top, this plane is not scoped to this function, so other functions in player.lua can access it.
plane.x = \_W/2; plane.y = \_H-plane.width-30;
plane.myName = "Hero";
physics.addBody(plane, { isSensor = true });
plane:prepare("flying");
plane:play();
-- Every plane gets assigned it's own collision label.
plane.collision = onPlaneCollision;
plane:addEventListener( "collision", plane );
return plane;
end
The way I did speedUp was shown in the Pow.lua code. I can’t for the life of me figure out why they don’t work in main, it is quite frustrating, I thought it would definitely have been resolved after reprogramming virtually everything to avoid global variables where possible and avoided the deprecated method of using modules.
Any additional help on this issue would be greatly appreciated.
[import]uid: 116225 topic_id: 20739 reply_id: 82433[/import]