I'm trying to run the most basic Haxe program but keep getting errors.
The Main.hx file looks like this:
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 = 640; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom).
var gameHeight:Int = 480; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom).
var initialState:Class<FlxState> = MenuState; // The FlxState the game starts with.
var zoom:Float = -1; // 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));
}
}
Just the generic template file. When I run it in Terminal (running Mac OS X El Capitan), I get this error:
Main.hx:8: characters 7-21 : Type not found : flixel.FlxGame
Haven't had problems with the installations or anything and I am new to Haxe so I don't know where to start. Any ideas?
Thanks :)
Did you add the library when you try to run your game ?
You can do that by using the command line haxe -lib flixel -main Main ....
Or by writting an hxml file containing all your CLI arguments :
-lib flixel
-main Main
Update after #Gama11 comment :
HaxeFlixel used the OpenFL format for the compilation information (see http://www.openfl.org/documentation/projects/project-files/xml-format/).
So you should include include flixel library using : <haxelib name="flixel" />in your Project.xml file.
Related
I have simple demo project. Image moved along screen follow mouse point.
LibGDX Image instance jump to default x coordinate along x axis, determined inside MainMenuScreen.kt show method, every time i click on screen, and start from default position moving. But i expect Image will continue/start new moving from last position before click on screen. How fix it, and what problem?
Code is simple and short, and i can't understand what can be wrong.
pastebin link to full project code:
https://pastebin.com/4UQDjSWa
github link to project:
https://github.com/3dformortals/demo-libgdx/tree/master/DemoMovingImageOnScreen
full project code:
//-------
//KDA.kt
//-------
package com.kda
import com.badlogic.gdx.Game
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.GL20
import gui.AnimationSkin as AniSkin
class KDA : Game() {
internal var screenWidth:Float = 0.0f
internal var screenHeight:Float = 0.0f
internal val aniskin:AniSkin = AniSkin() //incuded human.atlas TextureAtlas for animation
override fun create() {
screenWidth = Gdx.graphics.width.toFloat()
screenHeight = Gdx.graphics.height.toFloat()
aniskin.prepare() //call preparing method for connect human.atlas for later using for animation
}
override fun render() {
Gdx.gl.glClearColor(1f, 0f, 0f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
if (Gdx.input.justTouched()){
setScreen(MainMenuScreen(this))
}
super.render()
}
}
//-------------------
//AnimationSkin.kt
//-------------------
package gui
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.TextureAtlas
import com.badlogic.gdx.scenes.scene2d.ui.Skin
class AnimationSkin : Skin() {
fun prepare(){
addRegions(TextureAtlas(Gdx.files.internal("animation/human.atlas")))
}
}
//----------------------
//MainMenuScreen.kt
//----------------------
package com.kda
import animated.ImageMoving
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.ScreenAdapter
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.scenes.scene2d.Stage
import com.badlogic.gdx.utils.viewport.FitViewport
class MainMenuScreen(private val game: KDA) : ScreenAdapter() {
private val stage: Stage = Stage(FitViewport(game.screenWidth, game.screenHeight))
private val player = ImageMoving(game)
private val sprite = player.viewBox()
override fun show() {
Gdx.input.inputProcessor = stage
stage.isDebugAll = true //turn on frames around objects
sprite.x = 500f
//------------------------------------------------------------------------------------
//later, every mouse click on screen sprite jump to x500 position, and i can't fix it
//if i don't execute `sprite.x = 500f` , then sprite jump to x0 position, every click on screen
//--------------------------------------------------------------------------------------------
stage.addActor(sprite)
}
override fun resize(width: Int, height: Int) {
stage.viewport.update(width, height, true)
}
override fun render(delta: Float) {
super.render(delta)
Gdx.gl.glClearColor(0f, 0.5f, 0.5f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
if(Gdx.input.justTouched()) println("before calculateAction box.x= "+sprite.x.toString()) //500 always
player.calculateAction(delta) //call player method for calculation moving on screen
println(sprite.x) //print normal as expected
stage.act(delta)
stage.draw()
}
}
//-----------------
//ImageMoving.kt
//-----------------
package animated
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.kda.KDA
class ImageMoving(game: KDA) {
fun viewBox() = img
private val img = Image(game.aniskin.getDrawable("move-skin-male-back-R-0"))
fun calculateAction(delta:Float){
if (img.x > Gdx.input.x) img.x-=(100*delta).toInt().toFloat()
else if (img.x < Gdx.input.x) img.x+=(100*delta).toInt().toFloat()
}
}
//----------------------
//DesktopLauncher.kt
//---------------------
package com.kda.desktop
import com.badlogic.gdx.backends.lwjgl.LwjglApplication
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
import com.kda.KDA
object DesktopLauncher {
#JvmStatic
fun main(arg: Array<String>) {
val config = LwjglApplicationConfiguration()
config.height = 720
config.width = 1280
LwjglApplication(KDA(), config)
}
}
gif animation demo of jumping image to default position x=500 after clicking on screen
I trying to add a mp3 in to my scala gui using scalafx, but i have trouble how to add in to the scene
this is what i have, but it doesn't work...
val gameStage = new PrimaryStage {
title = "Game Graphics"
scene = new Scene(windowWidth, windowHeight) {
var audio = new Media(url)
var mediaPlayer = new MediaPlayer(audio)
mediaPlayer.volume = 100
mediaPlayer.play()
}
}
It appears that one problem is that you have not used a MediaView instance to add the MediaPlayer to the scene. Also, it's probably better if you do not start to play the media until the scene has been displayed.
I think you need something like this (as a complete app):
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.{Group, Scene}
import scalafx.scene.media.{Media, MediaPlayer, MediaView}
object GameGraphics
extends JFXApp {
// Required info. Populate as necessary...
val url = ???
val windowWidth = ???
val windowHeight = ???
// Initialize the media and media player elements.
val audio = new Media(url)
val mediaPlayer = new MediaPlayer(audio)
mediaPlayer.volume = 100
// The primary stage is best defined as the stage member of the application.
stage = new PrimaryStage {
title = "Game Graphics"
width = windowWidth
height = windowHeight
scene = new Scene {
// Create a MediaView instance of the media player, and add it to the scene. (It needs
// to be the child of a Group, or the child of a subclass of Group).
val mediaView = new MediaView(mediaPlayer)
root = new Group(mediaView)
}
// Now play the media.
mediaPlayer.play()
}
}
Also, you should prefer val to var, particularly if there is no need to modify the associated variables after they have been defined.
BTW, it's not possible to test your code, so please consider posting a minimal, complete and verifiable example next time.
Here's what I have so far. The background goes green (the colour of the Page), but I'd expect a purple ContentView with some text inside to fill the page, too.
Is there anything further I'm missing?
import { on, run, launchEvent } from "tns-core-modules/application";
import { Frame } from "tns-core-modules/ui/frame/frame";
import { ContentView } from "tns-core-modules/ui/content-view/content-view";
import { TextBase } from "tns-core-modules/ui/text-base/text-base";
import { Page } from "tns-core-modules/ui/page/page";
on(launchEvent, (data) => {
const frame = new Frame();
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textBase = new TextBase();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textBase.text = "Hello, world!";
contentView._addView(textBase);
page.bindingContext = contentView;
frame.navigate({ create: () => page });
data.root = page; // Incidentally, should this be the frame or the page?
});
run();
You are almost on track, you just need slight modification on your code.
import { on, run, launchEvent } from 'tns-core-modules/application';
import { Frame } from 'tns-core-modules/ui/frame/frame';
import { ContentView } from 'tns-core-modules/ui/content-view/content-view';
import { TextField } from 'tns-core-modules/ui/text-field';
import { Page } from 'tns-core-modules/ui/page/page';
run({
create: () => {
const frame = new Frame();
frame.navigate({
create: () => {
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textField = new TextField();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textField.text = "Hello, world!";
contentView.content = textField;
page.content = contentView;
return page;
}
});
return frame;
}
});
You don't have to wait for launch event, you could set the root frame in run method itself.
In your code, you were creating the frame but never adding it to root UI element or mark the frame itself as root element
It's recommended to use .content to add child for a ContentView / Page as they are originally designed to hold one child element only.
Use TextField / TextView for input text, TextBase is just a base class.
It seems to me that you try to overcomplicate. You can replace XML with code just by implementing createPage method - Create a page via code.
I just modified default NS + TypeScript Playground template to operate without XML - NS + TypeScript template without XML.
I think you can't leave run as empty as it is expecting an entry to start the app. From {NS} website,
You can use this file to perform app-level initializations, but the
primary purpose of the file is to pass control to the app's root
module. To do this, you need to call the application.run() method and
pass a NavigationEntry with the desired moduleName as the path to the
root module relative to your /app folder.
if you look for run code in "tns-core-modules/application"
function run(entry) {
createRootFrame.value = false;
start(entry);
}
exports.run = run;
and
function start(entry) {
if (started) {
throw new Error("Application is already started.");
}
started = true;
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
if (!androidApp.nativeApp) {
var nativeApp = getNativeApplication();
androidApp.init(nativeApp);
}
}
I have a quite simple unity GUI that has the following scheme :
Where Brekt and so are buttons.
The GUI works just fine on PC and is on screen space : overlay so it is supposed to be adapted automatically to fit every screen.
But on tablet the whole GUI is smaller and reduced in the center of the screen, with huge margins around the elements (can't join a screenshot now)
What is the way to fix that? Is it something in player settings or in project settings?
Automatically scaling the UI requires using combination of anchor,pivot point of RecTransform and the Canvas Scaler component. It is hard to understand it without images or videos. It is very important that you thoroughly understand how to do this and Unity provided full video tutorial for this.You can watch it here.
Also, when using scrollbar, scrollview and other similar UI controls, the ContentSizeFitter component is also used to make sure they fit in that layout.
There is a problem with MovementRange. We must scale this value too.
I did it so:
public int MovementRange = 100;
public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input
private int _MovementRange = 100;
Vector3 m_StartPos;
bool m_UseX; // Toggle for using the x axis
bool m_UseY; // Toggle for using the Y axis
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input
void OnEnable()
{
CreateVirtualAxes();
}
void Start()
{
m_StartPos = transform.position;
Canvas c = GetComponentInParent<Canvas>();
_MovementRange = (int)(MovementRange * c.scaleFactor);
Debug.Log("Range:"+ _MovementRange);
}
void UpdateVirtualAxes(Vector3 value)
{
var delta = m_StartPos - value;
delta.y = -delta.y;
delta /= _MovementRange;
if (m_UseX)
{
m_HorizontalVirtualAxis.Update(-delta.x);
}
if (m_UseY)
{
m_VerticalVirtualAxis.Update(delta.y);
}
}
void CreateVirtualAxes()
{
// set axes to use
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);
// create new axes based on axes to use
if (m_UseX)
{
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
}
if (m_UseY)
{
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
}
}
public void OnDrag(PointerEventData data)
{
Vector3 newPos = Vector3.zero;
if (m_UseX)
{
int delta = (int)(data.position.x - m_StartPos.x);
delta = Mathf.Clamp(delta, -_MovementRange, _MovementRange);
newPos.x = delta;
}
if (m_UseY)
{
int delta = (int)(data.position.y - m_StartPos.y);
delta = Mathf.Clamp(delta, -_MovementRange, _MovementRange);
newPos.y = delta;
}
transform.position = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.position);
}
I am just starting to learn actionscript, and to help get used to the syntax, I am challenging myself to make a simple game where you are a circle that shoots falling blocks.
For some reason every time I try to add a keyboard event listener the game doesn't run.
Here is my player file.
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Player extends Sprite
{
//Variables
private var playerRadius:Number = 50;
private var playerX:Number = 5;
private var playerY:Number = 5;
private var speed:Number = 0;
private var xvel:Number = 0;
public function Player()
{
init();
//Drawing
drawPlayer();
//Event Listeners
this.addEventListener(Event.ENTER_FRAME, updatePlayer);
stage.addEventListener(KeyboardEvent.KEY_DOWN, controlPlayer);
}
//Update
public function updatePlayer(event:Event):void{
this.x ++;
}
//Draw
private function drawPlayer():void{
graphics.beginFill(0xFF0000);
graphics.drawCircle(10,10,50);
graphics.endFill();
}
//Control
public function controlPlayer(event:KeyboardEvent):void{
if (event.keyCode == Keyboard.RIGHT) {
speed = 5;
}
}
}
}
With this code I just get a white screen, but if I comment out
stage.addEventListener(KeyboardEvent.KEY_DOWN, controlPlayer);
it works, but I don't have control of the player.
I'd appreciate any and all help!
Using your code I was able to figure out your issue which ultimately turned out to be a couple problems with your code. I'm surprised you were not seeing the following error in the Flash 'Output' Panel when you tested the application:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Player()
at Player_fla::MainTimeline/frame1()
The first issue is that when you create an object of the type Player, it isn't yet added to the Stage, so it does not yet have access to the stage object.
Once the player object is added to the Stage, only then will you be able to add the listener for keyboard events to the stage; however, for this to happen, your Player class needs to be made aware of the fact that an instance of it was added to the stage so that it knows exactly when it should register the keyboard event listener.
Here is an updated version of your code that should resolve these issues:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Player extends Sprite
{
//Variables
private var playerRadius:Number = 50;
private var playerX:Number = 5;
private var playerY:Number = 5;
private var speed:Number = 0;
private var xvel:Number = 0;
public function Player()
{
init();
//Drawing
drawPlayer();
//Event Listeners
this.addEventListener(Event.ENTER_FRAME, updatePlayer);
this.addEventListener(Event.ADDED_TO_STAGE, initKeyboardListener);
}
public function initKeyboardListener(event:Event) {
stage.addEventListener(KeyboardEvent.KEY_DOWN, controlPlayer);
}
//Update
public function updatePlayer(event:Event):void{
this.x++;
}
//Draw
private function drawPlayer():void{
graphics.beginFill(0xFF0000);
graphics.drawCircle(10,10,50);
graphics.endFill();
}
//Control
public function controlPlayer(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.RIGHT) {
this.speed = 5;
}
}
} // end class
} // end package
For all of this to work, don't forget to add the player object to the stage. I can only assume you have done this since you haven't shared any code showing where you use the Player class, but here is an example of what I am referring to:
import Player;
var player:Player = new Player();
stage.addChild(player);
Also, the keyboard listener simply alters the speed variable; however the speed variable hasn't been implemented anywhere else in your code, so you won't see the difference in the GUI until this is fixed. I verified that all the listeners were working as they should using trace statements.