black boxes instead of sprites on reload andengine - andengine

My sprites (which are boxes themselves, but different colors) are all showing as black boxes the second time my andengine activity is loaded. It's odd because usually this problem is due to the texture atlas not being large enough, but I tried doubling the size of the atlas, and this didn't work. So here's the relevant code, any help would be much appreciated!
So to put it out there, the first time I load my game, everything is fine and perfect, but the second time, the sprites appear black.
I've seen other questions where the sprites appear as black boxes but for me they load fine the first time, which does not happen for other questions, and the answers which were given on the other questions did not work for me (they were, atlas needs to be power of two, and atlas is not big enough)
public void loadGameResources(){
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
gameTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 512, 512, TextureOptions.BILINEAR);
blackTile = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "blacktile.png");
greyTile = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "greytile.png");
redTile = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "redtile.png");
greenTile = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "greentile.png");
Log.d(gameTextureAtlas+"","didn'tignore");
loadFont();
try{
Log.d("LOPOLL","arrived");
gameTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
Log.d("boom","arrived");
gameTextureAtlas.load();
Log.d("gotHere","arrived");
}catch(Exception e){
Log.d("WrongPlace","arrived");
}
}
(Resource unload method)
public void unloadGameResources(){
if(gameTextureAtlas !=null){
gameTextureAtlas.unload();
}
gameTextureAtlas = null;
// blackTile = null;
// greyTile = null;
// redTile = null;
// greenTile = null;
}
The reason that I commented the section giving the tiletextures a null value is that doing this for some reason created a nullexception error even though I thought the textureregions would be reassigned textures upon reloading the activity as reloading the activity calls the loadgameresources() method

Got the answer guys.. System.exit(code) ensures the activity is exited properly. Dissapointed stack overflow was not able to answer this!

Related

Graphics.RenderTexture() causes extra image to appear on canavas

I have some code like this:
readonly Rect WORK_SOURCE_RECT = new Rect(0f, 0f, 1f, 1f);
Color[] workPixels;
void Start() {
Texture2D workTexture = new Texture2D(256, 256, GraphicsFormat.R8G8B8A8_UNorm,
TextureCreationFlags.None);
workPixels = workTexture.GetPixels();
}
void OnGUI() {
workTexture.SetPixels(workPixels);
workTexture.Apply();
Graphics.DrawTexture(toRect, workTexture, WORK_SOURCE_RECT,
0, 0, 0, 0, renderColor);
}
void Update() {
// Omitted - Some changes are made by code here to the workPixels array.
}
The call to Graphics.DrawTexture() correctly draws the content of workTexture to the screen, just how I want it. But there is a strange side effect...
Any other GUI that is drawn inside of a scene object containing a Canvas component, will show an extra Y-reversed copy of the work texture. (Nevermind the reversal--not the issue.) I don't know why this extra image is drawn. It seems like there is a shared resource between two GUI things I'd hoped were completely unrelated.
In the image shown below, the reversed-face on the right is the unwanted extra render. Strangely it appears when I move to the right side of my scene, so it's like it is in world space. But it will update when GUI-based elements like subtitles are shown.
On Unity 2019.4.13f1 with MacOS.
The solution I found that resolved my problem was camera stacking. I created a second camera that was culled to just UI layer. The first camera had UI layer removed from culling. And then the calls to Graphics.DrawTexture() no longer appeared on the canvas used for UI.

Unity OnMatchList inaccesible due to its protection level

I have seen that there are more answers to similar questions, but none of these helped me. I hope you can.
I have a Unity2D shooter game and I try to make a menu for UNET. I watched a youtube tutorial from Brackeys to make the menu (https://youtu.be/V4oRs26vAw8?list=PLPV2KyIb3jR5PhGqsO7G4PsbEC_Al-kPZ&t=896) and when he runs the project it shows me the error: "error CS0122: 'UnityEngine.Networking.Match.ListMatchResponse' is inaccessible due to its protection level. I found out that this might happen when you access for example a private variable from another function, but I access a function from Unity and I can not modify its type (I believe). Any ideas? Thank you.
public void OnMatchList(bool success, string extendedInfo, ListMatchResponse matchList)
{
status.text = "";
if (matchList == null)
{
status.text = "Couldn't get room list.";
return;
}
ClearRoomList();
foreach(MatchDesc match in matchList.matches)
{
GameObject _roomListItemGO = Instantiate(roomListItemPrefab);
_roomListItemGO.transform.SetParent(roomListParent);
// Have a component sit on the gameobject
// that will take care of setting up the name / amount of users.
// as well as setting up a callback function that will join the game.
roomList.Add(_roomListItemGO);
}
}
'MatchDesc' has been renamed to 'MatchInfoSnapshot'.
Just replace it and it should work fine.

How to create a dynamic gradient background 2d in unity

I am new to unity and for my project I need a gradient background which changes after a certain amount of time. I searched a lot and not able to get it . Can anyone please explain me step by step with respective coding and procedures. Reference to this type of background is the mobile game stack
I think you can make it normaly by create 2 background. After a certain amount of time just fade old background and enable new background. Code example:
void ChangeBackground()
{
newImage.gameObject.SetActive(true);
StartCoroutine(FadeImage(0.1f));
}
IEnumerator FadeImage(float speedStep)
{
Color newColor = oldImage.color;
while (newColor.a > 0)
{
newColor.a -= speedStep;
oldImage.color = newColor;
yield return null;
}
oldImage.gameObject.SetActive(false);
}

How to avoid Thread.sleep() in a for loop from interrupting the UI Thread?

I have the following pseudo code to clarify my problem and a solution. My original posting and detailed results are on Stack Overflow at: Wait() & Sleep() Not Working As Thought.
public class PixelArtSlideShow { // called with click of Menu item.
create List<File> of each selected pixelArtFile
for (File pixelArtFile : List<File>) {
call displayFiles(pixelArtFile);
TimeUnits.SECONDS.sleep(5); }
}
public static void displayFiles(File pixelArtFile) {
for (loop array rows)
for (loop array columns)
read-in sRGB for each pixel - Circle Object
window.setTitle(....)
}
// when above code is used to Open a pixelArtFile, it will appear instantly in a 32 x 64 array
PROBLEM: As detailed extensively on the other post. Each pixelArtFile will display the setTitle() correctly and pause for about 5 secs but the Circle’s will not change to the assigned color except for the last file, after the 5 secs have passed. It's like all the code in the TimeUnits.SECONDS.sleep(5); are skipped EXCEPT the window.setTitle(...)?
My understanding is the TimeUnits.SECONDS.sleep(5); interrupts the UI Thread uncontrollable and I guess must somehow be isolated to allow the displayFiles(File pixelArtFile) to fully execute.
Could you please show me the most straight forward way to solve this problem using the pseudo code for a more completed solution?
I have tried Runnables, Platform.runLater(), FutureTask<Void>, etc. and I'm pretty confused as to how they are meant to work and exactly coded.
I also have the two UI windows posted on the web at: Virtual Art. I think the pixelArtFile shown in the Pixel Array window may clarify the problem.
THANKS
Don't sleep the UI thread. A Timeline will probably do what you want.
List<File> files;
int curFileIdx = 0;
// prereq, files have been appropriately populated.
public void runAnimation() {
Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(5), event -> {
if (!files.isEmpty()) {
displayFile(curFileIdx);
curFileIdx = (curFileIdx + 1) % files.size();
}
})
);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
// prereq, files have been appropriately populated.
public void displayFile(int idx) {
File fileToDisplay = files.get(idx);
// do your display logic.
}
Note, in addition to the above, you probably want to run a separate task to read the file data into memory, and just have a List<ModelData> where ModelData is some class for data you have read from a file. That way you wouldn't be continuously running IO in your animation loop. For a five second per frame animation, it probably doesn't matter much. But, for a more frequent animation, such optimizations are very important.

JavaFX Canvas Update

I've been working on switching my applications from Swing to JavaFX. I've been working on a room escape game which displays a description of the item on which the user clicks. In Swing, I'd subclass JComponent and override the paintComponent(Graphics) method. I could draw the text there, knowing that the method is constantly called to update the screen. However, using the JavaFX Canvas, there is no method that is called constantly, which makes this task harder. I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail. Here's the important code:
package me.nrubin29.jescape;
import javafx.application.Platform;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.shape.Rectangle;
import java.util.Timer;
import java.util.TimerTask;
public class RoomPane extends Canvas {
private Room room;
private Toast toast;
public RoomPane() {
super(640, 480);
setOnMouseClicked(e -> {
for (JObject o : room.getObjects()) {
if (o.getBounds().contains(e.getX(), e.getY())) {
toast = new Toast(o.getDescription());
}
}
});
new Timer().schedule(new TimerTask() {
#Override
public void run() {
if (toast == null) {
return;
}
if (toast.decrement()) { // Decrements the internal counter. If the count is 0, this method returns true.
toast = null;
Platform.runLater(() -> getGraphicsContext2D().restore());
}
else {
Platform.runLater(() -> getGraphicsContext2D().strokeText(toast.getText(), 300, 100));
}
}
}, 0, 1000);
}
public void changeRoom(Room room) {
this.room = room;
GraphicsContext g = getGraphicsContext2D();
g.drawImage(room.getBackground(), 0, 0);
for (JObject o : room.getObjects()) {
g.drawImage(o.getImage(), getCenterX(o.getBounds()), getCenterY(o.getBounds()));
}
g.save();
}
}
I attempted save()ing the GraphicsContext after I drew the images and called restore() when I wanted to remove the text, but to no avail.
save and restore have nothing to with removing things like text, what they do is save in a stack the state of various settings like a stroke or fill to use to draw shapes and allow them to be popped off the stack for application later. Those routines don't effect the pixels drawn on the canvas at all.
To remove something from a GraphicsContext, you can either draw over the of it, or clear it. For your code, what you could do is snapshot the canvas node where you are trying to save it, then draw your snapshot image onto the canvas where you are trying to restore it. It is probably not the most efficient way of handling drawing (a smarter routine which just draws only damaged area where the text is would be better, but probably not required for your simple game).
However, using the JavaFX Canvas, there is no method that is called constantly
Rather than using a timer to trigger canvas calls, use a AnimationTimer or a Timeline. The AnimationTimer has a callback method which is invoked every pulse (60 times a second, or as fast as JavaFX can render frames, whichever is the lesser), so it gives you an efficient hook into the JavaFX pulse based rendering system. The Timeline can have keyframes which are invoked at user specified durations and each keyframe can have an event handler callback which is invoked at that duration.
Using the built-in JavaFX animation framework, you don't have to worry about multi-threading issues and doing things like Platform.runLater which overly complicate your code and can easily lead to subtle and serious errors.
On a kind of unrelated note, for a simple game like this, IMO you are probably better off recoding it completely to use the JavaFX scene graph rather than a canvas. That way you will be working at a higher level of abstraction rather than clip areas and repainting damaged paint components.