I'm following the tutorial here... http://x01010111.com/haxeflixel.php#w3
I got to the part where he says "Awesome, but" and tried compiling, only to have nothing displayed. I tried comparing my code to his a bunch of times, going farther into the tutorial (I initially stopped when he first mentioned that there should only be a white background, and I compiled for comparison) to see if the problem would disappear (thinking it may have been somewhat outdated, etc.). I searched around looking for an explanation and found I didn't quite know what to search for, and didn't find anything that was helpful.
I haven't changed anything in my install, I've compiled many times previously without issue (numerous times in this same tutorial), so it's something in the Moving Forward section that I did wrong I'm thinking.
So, nothing is displayed, here's my PlayState.hx code.
package;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.FlxObject;
import flixel.tile.FlxTilemap;
import flixel.text.FlxText;
import flixel.ui.FlxButton;
import flixel.util.FlxMath;
import flixel.util.FlxStringUtil;
import flixel.FlxCamera;
import flixel.group.FlxGroup;
import flixel.text.FlxText;
import flixel.util.FlxTimer;
import openfl.Assets;
/**
* A FlxState which can be used for the actual gameplay.
*/
class PlayState extends FlxState
{
var level:FlxTilemap;
var player:FlxSprite;
/**
* Function that is called up when to state is created to set it up.
*/
override public function create():Void
{
FlxG.camera.bgColor = 0xFF6DC2CA;
addLevel();
addPlayer(2, 22);
setCamera();
super.create();
}
/**
* Function that is called when this state is destroyed - you might want to
* consider setting all objects this state uses to null to help garbage collection.
*/
override public function destroy():Void
{
super.destroy();
}
/**
* Function that is called once every frame.
*/
override public function update():Void
{
super.update();
FlxG.collide(level, player);
playerMovement();
}
function playerMovement():Void
{
player.velocity.x = 0;
if(FlxG.keys.pressed.LEFT) player.velocity.x -= 100;
if(FlxG.keys.pressed.RIGHT) player.velocity.x += 100;
if(FlxG.keys.justPressed.SPACE && player.isTouching(FlxObject.FLOOR)) player.velocity.y = -200;
}
function addLevel():Void
{
level = new FlxTilemap();
level.loadMap(Assets.getText("assets/data/Map1_Level.csv"), "Assets/images/tiles.png", 16, 16);
add(level);
}
function setCamera():Void
{
FlxG.camera.follow(player, FlxCamera.STYLE_PLATFORMER);
FlxG.camera.setBounds(0, 0, level.width - 16, level.height - 16, true);
}
function addPlayer(X:Int, Y:Int):Void
{
player = new FlxSprite(X * 16, Y * 16 - 8);
player.makeGraphic(6, 8, 0xFFFF0000);
player.acceleration.y = 800;
add(player);
}
}
And Main.hx...
package;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.Lib;
import flixel.FlxGame;
import flixel.FlxState;
class Main extends Sprite
{
var gameWidth:Int = 320; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom).
var gameHeight:Int = 240; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom).
var initialState:Class<FlxState> = PlayState; // The FlxState the game starts with.
var zoom:Float = 2; // If -1, zoom is automatically calculated to fit the window dimensions.
var framerate:Int = 60; // How many frames per second the game should run at.
var skipSplash:Bool = false; // Whether to skip the flixel splash screen that appears in release mode.
var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets
// You can pretty much ignore everything from here on - your code should go in your states.
public static function main():Void
{
Lib.current.addChild(new Main());
}
public function new()
{
super();
if (stage != null)
{
init();
}
else
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(?E:Event):Void
{
if (hasEventListener(Event.ADDED_TO_STAGE))
{
removeEventListener(Event.ADDED_TO_STAGE, init);
}
setupGame();
}
private function setupGame():Void
{
var stageWidth:Int = Lib.current.stage.stageWidth;
var stageHeight:Int = Lib.current.stage.stageHeight;
if (zoom == -1)
{
var ratioX:Float = stageWidth / gameWidth;
var ratioY:Float = stageHeight / gameHeight;
zoom = Math.min(ratioX, ratioY);
gameWidth = Math.ceil(stageWidth / zoom);
gameHeight = Math.ceil(stageHeight / zoom);
}
addChild(new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen));
}
}
I've been running into a number of problems so far with Haxeflixel and with the exception of a previous out of date tutorial it's always been something stupid that I did wrong.
Edit: I tried using debug mode to show more information, but it didn't show any errors, or anything else for that matter. I hit ~ to see if there was anything I missed there and, again, nothing. What am I looking for in debug mode?
I'm using the Flash Player Projector Content Debugger to run my .swf
Added Main.hx
Attempting to run that code with the assets provided by the tutorial I received the following runtime error in my editor output panel (I am using sublime text)
Assets.hx:149: [openfl.Assets] There is no BitmapData asset with an ID of "Assets/images/tiles.png"
If we look at PlayState.hx on line 76 we can see it is attempting to load the asset "Assets/images/tiles.png". Asset lookups are case sensitive and the asset directory is in fact lowercase by default, so this needs changing to "assets/images/tiles.png"
After doing so that code ran fine for me.
Note that I'm not using flash for debugging this, but neko. if you're having trouble reading debug output in flash you might be best testing with neko first, and then later deploying for flash or your target platfokrm.
Related
basically the question. I'm trying to make a game where you need to draw certain shapes to do certain actions. I want to have the game trace the movement of the cursor, but I can't find any good way to make the lines.
I'v tried using FlxSpriteUtil.drawLine, but that doesn't seem to work. I've also tried using FlxSpriteGroups.clone() to clone a dot as the cursor, but that just leaves a trail of dots, so that doesn't work either.
I'm really new to Haxe and HaxeFlixel, so I have no idea what to do or what to use. Any suggestions?
Sounds like you started off right by using drawLine from FlxSpriteUtil. When making a drawable line, the easiest way to do it is to just save the previous mouse position in a variable, and draw a line from the previous position to the current position every frame (i.e. put the code in update()).
Here's a small code example which creates a canvas sprite which allows drawing.
package;
import flixel.FlxG;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.math.FlxPoint;
import flixel.util.FlxColor;
using flixel.util.FlxSpriteUtil;
class PlayState extends FlxState
{
private var canvas:FlxSprite;
private var lastPoint:FlxPoint;
private static inline var CANVAS_OFFSET = 16;
private static inline var DRAW_THICKNESS = 2;
private static inline var DRAW_COLOR = FlxColor.BLACK;
override public function create()
{
super.create();
canvas = new FlxSprite(CANVAS_OFFSET, CANVAS_OFFSET);
canvas.makeGraphic(256, 256, FlxColor.WHITE);
add(canvas);
}
override public function update(elapsed:Float)
{
super.update(elapsed);
if (FlxG.mouse.pressed && FlxG.mouse.overlaps(canvas))
{
if (FlxG.mouse.justPressed)
{
// This is the first point, i.e. the beginning of a new stroke
lastPoint = FlxG.mouse.getPosition();
// First, create an ellipsis to enable the player to click to draw a line
canvas.drawEllipse(
FlxG.mouse.x - CANVAS_OFFSET,
FlxG.mouse.y - CANVAS_OFFSET,
DRAW_THICKNESS / 2,
DRAW_THICKNESS / 2,
DRAW_COLOR
);
}
else
{
// Otherwise, line to the previously drawn point
var mousePos = FlxG.mouse.getPosition();
canvas.drawLine(
lastPoint.x - CANVAS_OFFSET,
lastPoint.y - CANVAS_OFFSET,
mousePos.x - CANVAS_OFFSET,
mousePos.y - CANVAS_OFFSET,
{
thickness: DRAW_THICKNESS,
color: DRAW_COLOR
}
);
lastPoint = mousePos;
}
}
}
}
I have two 3d buttons in my scene and when I gaze into any of the buttons it will invoke OnPointerEnter callback and saving the object the pointer gazed to.
Upon pressing Fire1 on the Gamepad I apply materials taken from Resources folder.
My problem started when I gazed into the second button, and pressing Fire1 button will awkwardly changed both buttons at the same time.
This is the script I attached to both of the buttons
using UnityEngine;
using UnityEngine.EventSystems;
using Vuforia;
using System.Collections;
public class TriggerMethods : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
Material _mat;
GameObject targetObject;
Renderer rend;
int i = 0;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Fire1"))
TukarMat();
}
public void OnPointerEnter(PointerEventData eventData)
{
targetObject = ExecuteEvents.GetEventHandler<IPointerEnterHandler>(eventData.pointerEnter);
}
public void OnPointerExit(PointerEventData eventData)
{
targetObject = null;
}
public void TukarMat()
{
Debug.Log("Value i = " + i);
if (i == 0)
{
ApplyTexture(i);
i++;
}
else if (i == 1)
{
ApplyTexture(i);
i++;
}
else if (i == 2)
{
ApplyTexture(i);
i = 0;
}
}
void ApplyTexture(int i)
{
rend = targetObject.GetComponent<Renderer>();
rend.enabled = true;
switch (i)
{
case 0:
_mat = Resources.Load("Balut", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 1:
_mat = Resources.Load("Khasiat", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 2:
_mat = Resources.Load("Alma", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
default:
break;
}
}
I sensed some logic error and tried making another class to only manage object the pointer gazed to but I was getting more confused.
Hope getting some helps
Thank you
TukarMat() is beeing called on both buttons when you press Fire1. If targetObject is really becoming null this should give an error on first button since it's trying to get component from a null object. Else, it'll change both as you said. Make sure OnPointerExit is beeing called.
Also, it seems you are changing the shared material.
The documentation suggests:
Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.
It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.
So, try changing the material property instead of sharedMaterial since it'll change the material for that object only.
I'm trying to make a game where you can capture floating lights that moves randomly in the air. In the game there is going to be 3 different boxes where you can put the floating lights, so there is also going to be 3 different lights.
The lights works properly and I am able to drag them around like I want.
My issue is how to catch them and re-spawn them. I want to use the kill() method that you find in the flixel.FlxNapeSprite.
When you catch them, you should move them to the correct box, and when they come inside the box, they should get killed, you get points, and a new random light re spawn.
Link to image of the game so far
How do I kill the light-object inside a certain area?
I guess the boxes are FlxNapeSprites as well? Typically you would set up a collision callback here, which is called whenever the hitboxes of two nape bodies overlap (the light and the box in this case). You can display the nape bodies with napeDebugEnabled = true or by pressing the "N" button in the top right of flixel's debugger overlay.
Here's a simple example of how to set up a simple collision callback using Flixel + Nape:
package;
import flixel.addons.nape.FlxNapeSprite;
import flixel.addons.nape.FlxNapeState;
import flixel.util.FlxColor;
import nape.callbacks.CbEvent;
import nape.callbacks.CbType;
import nape.callbacks.InteractionCallback;
import nape.callbacks.InteractionListener;
import nape.callbacks.InteractionType;
import nape.phys.BodyType;
using flixel.util.FlxSpriteUtil;
class PlayState extends FlxNapeState
{
override public function create()
{
super.create();
bgColor = FlxColor.BLACK;
napeDebugEnabled = true;
var light = new Light(10, 10);
var box = new Box(10, 100);
add(light);
add(box);
light.body.velocity.y = 200;
FlxNapeState.space.listeners.add(new InteractionListener(
CbEvent.BEGIN,
InteractionType.COLLISION,
Light.CB_TYPE,
Box.CB_TYPE,
collideLightBox));
}
function collideLightBox(callback:InteractionCallback)
{
var light:Light = cast callback.int1.castBody.userData.sprite;
light.kill();
}
}
class Light extends FlxNapeSprite
{
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(10, 10, FlxColor.TRANSPARENT);
var radius = 5;
drawCircle(5, 5, radius, FlxColor.WHITE);
createCircularBody(radius);
body.cbTypes.add(CB_TYPE);
// we need this to get the Light instance in the callback later
body.userData.sprite = this;
}
}
class Box extends FlxNapeSprite
{
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(100, 50, FlxColor.GREEN);
createRectangularBody(width, height);
body.cbTypes.add(CB_TYPE);
body.type = BodyType.STATIC;
}
}
Be sure to check out the official FlxNape demo. The Nape website also has some very helpful examples + docs.
ActionScript 3.0
Essentially I need a function that displays a random number of butterfly objects. (Also I should make a reset function that resets the first function.)
I find though that the butterflies are not even displayed to begin with, It seems that the children are not being added to the stage even though I used the addChild().
Any help is appreciate thanks!
// Random Number
var randomNumber : int = Math.floor(Math.random() * 8);
// New Sprite
var bContainer: Sprite = new Sprite();
this.addChild(bContainer);
var butterfly: MovieClip = new Butterfly();
bContainer.addChild(butterfly);
//Function to Create Butterfly Objects:
function showButterfly(randomNumber:int):void {
while(bContainer.numChildren < randomNumber){
bContainer.addChild(butterfly);
}
//Reset Function, I am not sure about this (especially the second one)
function button(evt:MouseEvent): void {
if(numChildren>0) {
removeChildAt(0);
}
if(numChildren==0) {
showButterfly();
}
}
// Event Listener
button.addEventListener(MouseEvent.MOUSE_DOWN);
//
I'm not completely sure, but aren't you suppose to set the width and height for the sprite that works as a holder object?
var bContainer: Sprite = new Sprite();
bContainer.graphics.beginFill(0xffffff);
bContainer.graphics.drawRect(0, 0,stage.stageWidth, stage.stageHeight);
addChildAt(bContainer, 0);
I have here a bubble popping game where bubbles fall from top of the game to the bottom and the player tries to pop as many bubbles as possible in 30 seconds. It is a 3 frame game, 1st frame is the start button, 2nd frame is the game, 3rd frame is the score and play again.
1st frame: Buttons to go to the second frame
2nd Frame: timer to count 30 seconds of play time
3rd frame: buttons to play again.
ScoreValue is a dynamic textbox in the last frame of the game. It records the points based on size the size scale of the bubble, and should be change based on the amount of bubbles the player has popped.
scoreValue.text = score.toString();
Error 1120: Access of unidentified property scoreValue
Anyways here the full package of the code.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.media.Sound;
import flash.geom.ColorTransform;
public class Ball extends MovieClip{
static public var burstCounter: uint;
private var vx: Number;
private var vy: Number;
private var gravity: Number;
private var stageWidth;
private var stageHeight;
private var bubble:Ball = new Ball();
private var score: uint=0;
public function Ball() {
bubble.addEventListener(Event.ADDED_TO_STAGE, initialize)
bubble.addEventListener(MouseEvent.CLICK, burst)
bubble.addEventListener(Event.ENTER_FRAME, dropping)
}
public function initialize (e:Event):void
{
bubble.x = Math.random() * stageWidth;
bubble.y = 0;
stageWidth = stage.stageWidth;
stageHeight = stage.stageHeight;
bubble.vx = Math.random() * 2 - 1;
bubble.vy = Math.random() * 2 + 1;
gravity = 0.1;
var sizeScale = Math.random() * 1.2 + .6;
bubble.scaleX = bubble.scaleY = sizeScale;
score = (10 / sizeScale);
scoreValue.text = score.toString();
var colorTran = new ColorTransform();
colorTran.color = Math.random() * 0xFFFFFF;
transform.colorTransform = colorTran;
addChild(bubble);
}
function dropping(e: Event) :void
{
x += vx;
y += vy;
vy += gravity;
if((x<0) || (x>stageWidth) || (y<0) || (y>stageHeight))
{
if(parent != null)
{
parent.removeChild(this);
}
removeEventListener(Event.ENTER_FRAME, dropping)
}
}
function burst (e:Event):void
{
var ballonPopping: Sound = new BalloonPopping();
bubble.removeEventListener(Event.ADDED_TO_STAGE, initialize);
bubble.removeEventListener(Event.ENTER_FRAME, dropping);
removeChild(bubble);
ballonPopping.play();
burstCounter += score;
}
}
}
Im getting this as output in my program, does any one know why?
Fonts should be embedded for any text that may be edited at runtime, other than text with the "Use Device Fonts" setting. Use the Text > Font Embedding command to embed fonts.
Thanks for your time.
you need to import the MouseEvent class to fix the 'Access undefined property of MouseEvent'
add this to your import statements:
import flash.events.MouseEvent;
Firstly, in a class, functions should be defined as public or private. Second, your burst function is expecting an Event while you are assigning a MouseEvent to it. Its an easy mistake that I use to often do.
Change it to:
private function burst (e:MouseEvent):void
The font thing in the output panel means you have a dynamic text field somewhere. Simply go to your FLA, open up that textfield and on the properties panel, hit the embed button and choose the Basic Latin checkbox...or numerals if its just numbers
edit: Also change your import to
import flash.events.*;
or add
import flash.events.MouseEvent;