I am trying Libgdx Game Class to make a game.And I am following a book.There is an example. Example has 4 classes and 1 DesktopLauncher. DesktopLauncher use StarfishCollector3() class to main function. Despite I dont call create method and render method which are in GameBeta abstract class to StarfishCollector3, the project is working.Can you explain what I dont know.
class StarfishCollector3 : GameBeta() {
var turtle:Turtle=null
var starfish:ActorBeta=null
var ocean:ActorBeta=null
var winMessage:ActorBeta=null
var win:Boolean = true
override fun initialize() {
ocean= ActorBeta()
ocean.setTexture(Texture( Gdx.files.internal("water.jpg") ))
mainStage.addActor(ocean)
starfish = ActorBeta();
starfish.setTexture(Texture(Gdx.files.internal("starfish.png")) );
starfish.setPosition( 380F,380F );
mainStage.addActor( starfish );
turtle = Turtle()
turtle.setTexture( Texture(Gdx.files.internal("turtle-1.png")) )
turtle.setPosition( 20F,20F )
mainStage.addActor( turtle )
winMessage = ActorBeta();
winMessage.setTexture( Texture(Gdx.files.internal("you-win.png")) );
winMessage.setPosition( 180F,180F );
winMessage.setVisible( false );
mainStage.addActor( winMessage );
win = false }
override fun update(dt: Float) {
if (turtle.overlaps(starfish as ActorBeta)){
starfish.remove()
winMessage.setVisible(true)} }
}
abstract class GameBeta: Game() {
protected var mainStage: Stage=null
abstract fun initialize()
override fun create() {`
mainStage = Stage()
initialize() }
abstract fun update(dt:Float)
.
override fun render() {
var dt= Gdx.graphics.getDeltaTime()
mainStage.act()
update(dt)
Gdx.gl.glClearColor(0F,0F,0F,1F)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
mainStage.draw()
}
}
The heirarchy of StarfishCollector3 is that it extends GameBeta, which extends Game, which implements ApplicationListener.
In DesktopLauncher you instantiate a StarfishCollector3 and pass it as an implicit ApplicationListener to an Application constructor by calling something like new LwjglApplication(starfishCollectior, config);. When you instantiate that LwjglApplication (or Lwjgl3Application or AndroidApplication, etc. depending on backend), the constructor of that Application class sets up the game engine. It creates all the classes for managing OpenGL and drawing the game in a repeating loop, pausing and resuming, etc.
So the Application class is using your StarfishCollector3 as an ApplicationListener and calling its relevant lifecycle methods at the appropriate times.
Related
I want to access a member of the MainFragment class from PersonAdapter class but none of them are available. I tried making both the classes and the members public and private also but so far nothing worked.
I guess I'm missing something obvious but I just can't figure it out.
class MainFragment : Fragment() {
lateinit var personAdapter: PersonAdapter
lateinit var personListener: OnPersonSelected
private var realm: Realm by Delegates.notNull()
lateinit var realmListener: RealmChangeListener<Realm>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.fragment_main, container, false)
return v
}
class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
var localPersonList = personList
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(localPersonList[position])
holder.itemView.setOnClickListener {
Toast.makeText(context, "click", Toast.LENGTH_SHORT).show()
//I want to reach personListener from here
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent!!.context).inflate(R.layout.person_list_item, parent, false)
return ViewHolder(v)
}
}}
In Kotlin, nested classes cannot access the outer class instance by default, just like nested static classes can't in Java.
To do that, add the inner modifier to the nested class:
class MainFragment : Fragment() {
// ...
inner class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
// ...
}
}
Note that an inner class holds a reference to its containing class instance, which may affect the lifetime of the latter and potentially lead to a memory leak if the inner class instance is stored globally.
See: Nested classes in the language reference
In Kotlin, there are 2 types of the nested classes.
Nested Class
inner Class
Nested class are not allowed to access the member of the outer class.
If you want to access the member of outer class in the nested class then you need to define that nested class as inner class.
class OuterClass{
var name="john"
inner class InnerClass{
//....
}
}
Add inner
Note that Android Studio's Code completion(IntelliSense) doesn't work right inside the inner class
class OuterClass {
val outerVariable = "Hello, World!"
inner class InnerClass {
// Code completion doesn't work here
val innerVariable = outerVariable // Code completion work
fun innerFunction() {
// Code completion work
}
}
}
There are three classes.
// in external library, which I don't want to modify
class ComponentBase {
// I want calling this to be disallowed
forceUpdate() {}
}
class ComponentBase_MyVersion extends ComponentBase {
// I want subclasses to always call this, instead of forceUpdate()
Update() {}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// I want this to be disallowed
this.forceUpdate();
// forcing the subclass to call this instead
this.Update();
}
}
How can I accomplish this, with changes only to ComponentBase_MyVersion?
Is there a way to "hide" a base-class member?
Or perhaps a way to override the definition -- like with the "new" keyword in C# -- letting me mangle the method definition to at least make warnings appear when attempting to call it?
The OOP does not allow you to do this kind of method cancellation. You can impleement this funcion on your class with an Exception like you suggested, or use a composition: https://en.wikipedia.org/wiki/Composition_over_inheritance
Example 1:
class ComponentBase {
forceUpdate() {}
}
class ComponentBase_MyVersion extends ComponentBase {
Update() {}
forceUpdate() {
throw new Error("Do not call this. Call Update() instead.");
}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// wil raise an exception
this.forceUpdate();
this.Update();
}
}
Example 2 (composition):
class ComponentBase {
forceUpdate() {}
}
class ComponentBase_MyVersion {
private _component: ComponentBase = ...;
Update() {}
// expose _component desired members ...
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// compilation error
this.forceUpdate();
this.Update();
}
}
I hope I helped.
Encapsulate implementation by replacing inheritance with composition Delegation Pattern
You can do this by adding the private access modifier on the forceUpdate method. This will result in all the subclasses being unable to access forceUpdate. However TypeScript does not support package access modifiers, but you can do this by replacing inheritance with composition.
class ComponentBase {
forceUpdate() {
}
}
class ComponentBase_MyVersion {
// Replace inheritance with composition.
private component: ComponentBase;
Update() {
this.component.forceUpdate();
}
}
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// Now subclass can't access forceUpdate method
this.Update();
}
}
Use a symbol in order to prevent external access to the method.
If you don't want to replace inheritance with composition, you can use Symbol to define a method. If your target is es5 you must configure tsconfig.json compilerOptions.lib to include es2015.symbol. Because every symbol is unique, any external module will not be able to obtain the symbol and access the method.
// libs.ts
let forceUpdate = Symbol("forceUpdate");
export class ComponentBase {
[forceUpdate]() {
}
}
export default class ComponentBase_MyVersion extends ComponentBase {
Update() {
this[forceUpdate]();
}
}
// test.ts
import ComponentBase_MyVersion from "./libs";
class MyComponent extends ComponentBase_MyVersion {
DoSomething() {
// Now subclass can't access the forceUpdate method.
this.Update();
}
}
I found a way that seems to work -- that is, which causes warnings to appear when someone attempts to call forceUpdate() on a subclass instance.
forceUpdate(_: ()=>"Do not call this. Call Update() instead.") {
throw new Error("Do not call this. Call Update() instead.");
}
Now when I write new MyComponent().forceUpdate(), I get a compiler error, with the warning message containing a description telling me to use Update() instead.
EDIT: Apparently this only works because the base class already had this definition:
forceUpdate(callBack?: () => any): void;
If instead the base method is defined with no arguments originally (as in the OP), the above solution doesn't work.
However, if you have a case like mine (where there's an optional property like that, which you can narrow the return-type of), it works fine. (not sure if this return-type-narrowing is a bug, or intended)
Hope one of you angular2 / typescript wizards can help out or at least provide a pointer in the right direction, before I got crazy :-)
Here is what I'd like to
have a parent class that implements it's own defined parent Interface, however using Generic Types so I can when creating a child class provide it with the child's specific and tailored class & data Interface.
the child class should be able to extend the parent data class by
being able to overwrite default/parent set variables
overwriting parent functions() and have the child's version called instead of the parent's default
In the below pseudo code example, I would like the call to the child's (inherited) someOtherfunction() to return "2"...
Am I asking for too much?
I can't seem to find any decent examples on the web...
How do I get this right?
Thank you -
Oliver
(CODE BELOW MAY BE BROKEN, IT'S JUST FOR ILLUSTRATION)
//
// Parent Class
//
export interface ICoreData <T> {
observeItems: Observable <T[]> ;
items: Array <T>;
}
#Injectable()
export class CoreData<T> implements ICoreData<T> {
public observeItems: Observable<T[]>;
private items: Array<T>;
constructor( 'Dependency Injection...' ) {}
coreFunction(): number {
return 1;
}
someOtherfunction(){
return this.coreFunction();
}
}
//
// Child class
//
export interface IMyDataStructure {
name: string;
age: string;
}
export interface ISpecificData extends ICoreData<IMyDataStructure> {
someExtraKey: number;
}
#Injectable()
export class SpecificData extends CoreData<IMyDataStructure> implements ISpecificData {
constructor() {
super();
}
coreFunction(): number{
//
// This function should "overwrite" the parent's original function
// and be called by the parent's someOtherfunction() function
//
return 2;
}
}
You're not asking too much. However you can't use interfaces to accomplish what you're trying to accomplish. You need to extend a class, which can be generic.
An interface is simply a contract, or a blueprint if you like, for a data type. There is no functionality associated with an interface. However in your case you wanted to be able to have methods on the base class; methods you could override in the derived.
The way I usually do this is to declare an abstract base class (so that the base class can't be instantiated itself), and then extend classes from that. Here's an example:
Note, I've removed all the Angular2 cruft in order to keep the example as simple as possible.
abstract class Base<T> {
constructor(public controlled: T) { }
doIt(): string {
return `Base.doIt: ${JSON.stringify(this.controlled)}`;
}
doSomethingElse(): string {
return `Base.doSomethingElse: ${JSON.stringify(this.controlled)}`;
}
};
interface Foo {
foo: string;
bar: string;
};
class Derived extends Base<Foo> {
constructor(foo: Foo) {
super(foo);
}
doSomethingElse(): string {
return `Derived.doSomethingElse: ${JSON.stringify(this.controlled)}`;
}
};
let d: Derived = new Derived({ foo: 'foo', bar: 'bar' });
console.log(`doIt ==> ${d.doIt()}`);
console.log(`doSomethingElse ==> ${d.doSomethingElse()}`);
Output:
doIt ==> Base.doIt: {"foo":"foo","bar":"bar"}
doSomethingElse ==> Derived.doSomethingElse: {"foo":"foo","bar":"bar"}
Playground link.
Is it possible to use addChild() without 'extends' from another Class ?
It's strange, that i need to extension from another classes to use it ... but maybe its my lack of knowledge in as3 ...
Main:
public class Main extends Sprite
{
private var sprite:Sprite = new Sprite();
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var myVar:MyClass = new Myclass();
addChild(myVar);
}
}
MyClass:
public class MyClass
{
private var sprite:Sprite = new Sprite();
public function MyClass()
{
sprite.graphics.lineStyle(1, 0x990000, 1);
sprite.graphics.drawRoundRect(5, 5, 500, 150, 10, 10);
addChild(sprite);
}
}
addChild is method that add's DisplayObject to DisplayObjectContainer, so yes, you must extend your custom classes if you want to see it on screen
futher reading: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html
I looks like you're trying to do this:
public class MyClass
{
private var sprite:Sprite;
public function MyClass(container:MovieClip)
// ^^^^^^^^^ Take a reference to a container to add children to.
{
sprite = new Sprite()
sprite.graphics.lineStyle(1, 0x990000, 1);
sprite.graphics.drawRoundRect(5, 5, 500, 150, 10, 10);
container.addChild(sprite);
// ^^^^^^ Add internal sprite to the referenced container.
}
}
Where you provide a container to add children to.
Meaning your Main class will simply pass a reference to itself to your MyClass instance.
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var myVar:MyClass = new MyClass(this);
// ^^^^ Simply pass the main class as the container.
}
Another option is to simply expose sprite from MyClass and then use:
addChild(myVar.sprite);
In your Main class.
The simple answer to your question is: no, a custom class cannot addChild without extending a subclass of DisplayObjectContainer. The method addChild() and its related methods are defined in DisplayObjectContainer and only subclasses of it can use them.
You often see the method addChild() used without a calling object (ex: theobject.addChild()) but that's only because the keyword "this" is implied. In reality addChild() is always called by a DisplayObjectContainer instance.
My game uses a variety of different game modes, and I'd like to spawn a different GameController script at the beginning of the scene depending on the game mode selected. Then other items (e.g., Enemies), would reference the main GameController, whether that be GameController_Mode1, GameController_Mode2, etc. But how can I have other objects referencing this if I don't know the type?
Unity iOS requires strict unityscript typing, so I can't use duck typing to get around this.
You can do this the same way you'd do it in C#, polymorphism. Derive all of your controllers from a single base Controller class. Then your GameController var can be set to any instantiation of a derived controller (see Start() in the example below).
Here is a quick example using a simple controller:
#pragma strict
var controller : MyController;
class MyController {
var data : int;
public function MyController(){
this.data = 42;
}
public function Print(){
Debug.Log("Controller: " + this.data);
}
}
class MyController1 extends MyController {
public function MyController1(){
this.data = 43;
}
public function Print(){
Debug.Log("Controller1: " + this.data);
}
}
class MyController2 extends MyController {
public function MyController2(){
this.data = 44;
}
public function Print(){
Debug.Log("Controller2: " + this.data);
}
}
function Start () {
controller = new MyController();
controller.Print(); // prints Controller: 42
controller = new MyController1();
controller.Print(); // prints Controller1: 43
controller = new MyController2();
controller.Print(); // prints Controller2: 44
}
I'm making any assumption that your gamecontrollers share function names and that the only difference is the code in each function.
[Update]
Regarding Heisenbug's comment below: You can use GetComponent to get the base class controller if your controller is a component.
Baseclass(BaseController.js):
class BaseController extends MonoBehaviour{
public function Print(){
Debug.Log("BaseController");
}
}
Extended class(Controller1.js):
class Controller1 extends BaseController {
public function Print(){
Debug.Log("Controller1: " + this.data);
}
}
Test:
var controller : BaseController;
controller = gameObject.GetComponent("BaseController"); //.GetComponent(BaseController) also works
controller.Print(); // will print "Controller1" if actual attached component is a Controller1 type
While it looks like there are some good answers already but it is worth mentioning Unity's SendMessage system. It is a really simple approach if all you need to do is call functions on the other object SendMessage.
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.SendMessage.html
In short you can use the following syntax:
TargetGameObject.SendMessage("targetFunction", argument, SendMessageOptions.DontRequireReceiver);
You can also use SendMessage to call javascript functions from C# scripts or vice versa.