I am new to Allegro (5) and I am making my first game. I need to put an image as background and a little square that moves in front of it.
In my code, on each frame the image is drawn at the (0;0) coordinates and then the square is drawn at (something;something), and, I think, it should appear over the image because it was drawn after it, but it doesn't.
Can someone explein me how to do this? Thanks
PS : Looking around in the Internet I found that this could have something to do with blitting, could someone explain me what that operation is?
I'll post the code to just draw the background on display. And I'll explain it little by little
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#define BACKGROUND_FILE "background.png"
int main(void){
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_BITMAP *background=NULL;
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
al_init_image_addon();//should check for errors
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
return -1;
}
background=al_load_bitmap(BACKGROUND_FILE);
if(!background)
{
fprintf(stderr, "failed to load background bitmap!\n");
return -1;
}
al_draw_bitmap(background,0,0,0);
al_flip_display();
al_rest(2.0);
al_destroy_display(display);
al_destroy_bitmap(background);
al_uninstall_system();
return 0;
}
This part starts up allegro, al_init starts up the allegro system, and al_init_image_addon lets us use bitmaps which is how allegro manages images:
if(!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
al_init_image_addon();//should check for errors
Here we create a display and check if it was successfully created:
display = al_create_display(640, 480);
if(!display) {
fprintf(stderr, "failed to create display!\n");
return -1;
}
Here we load an image, you just simply put in the file name and allegro will load it for you returning a ALLEGRO_BITMAP * (NULL if unsuccessful). After calling al_load_bitmap we check if the bitmap was successfully loaded.
background=al_load_bitmap(BACKGROUND_FILE);
if(!background)
{
fprintf(stderr, "failed to load background bitmap!\n");
return -1;
}
Allegro draws to a backbuffer, what this means is that it won't directly draw to the display. Instead, it will draw to a copy of the display(backbuffer) and once you flip the backbuffer(al_flip_display()), this copy (which you were drawing on top of) will show up all at once.
This can be see seen here:
al_draw_bitmap(background,0,0,0);
al_flip_display();
If you're going to be initializing lots of allegro stuff, you might want to initialize all together like for example :
int allegro_startup(void)
{
if(al_init())
{
if(al_init_primitives_addon())
{
if(al_install_keyboard())
{
if(al_install_mouse())
{
if(al_init_image_addon())
{
al_init_font_addon(); //Void
if(al_init_ttf_addon())
{
if(al_install_audio())
{
if(al_init_acodec_addon())
{
if(al_reserve_samples(1))
{
return AL_STARTUP_SUCCESS;
}
else
fprintf(stderr,"ERROR: Failed to reserve samples:(\n");
//al_shutdown_acodec_addon(); Does not exist
}
else
fprintf(stderr,"ERROR: Failed to initialize acodec addon\n");
al_uninstall_audio();
}
else
fprintf(stderr,"ERROR: Failed to install audio\n");
al_shutdown_ttf_addon();
}
else
fprintf(stderr,"ERROR: Failed to initialize ttf addon\n");
al_shutdown_font_addon();
al_shutdown_image_addon();
}
else
fprintf(stderr,"ERROR: Failed to initialize image addon\n");
al_uninstall_mouse();
}
else
fprintf(stderr,"ERROR: Failed to install mouse\n");
al_uninstall_keyboard();
}
else
fprintf(stderr,"ERROR: Failed to load primitives addon\n");
al_shutdown_primitives_addon();
}
else
fprintf(stderr,"ERROR: Failed to install keyboard\n");
al_uninstall_system();
}
else
fprintf(stderr,"ERROR: Failed to initialize allegro system\n");
return AL_STARTUP_ERROR;
}
void allegro_shut_down(ALLEGRO_DISPLAY *display,ALLEGRO_EVENT_QUEUE *event_queue)
{
al_destroy_display(display);
al_destroy_event_queue(event_queue);
al_uninstall_audio();
al_shutdown_ttf_addon();
al_shutdown_font_addon();
al_shutdown_image_addon();
al_uninstall_mouse();
al_uninstall_keyboard();
al_shutdown_primitives_addon();
al_uninstall_system();
}
Here are a lot of tutorials which are a lot more clearer and a little broader subjects if you're interested.
Related
I try this function but doesn't work
Future<void> _connect(BluetoothDevice device) async {
if (device == null) {
show('No device selected.');
} else {
bluetooth.isConnected.then((isConnected) {
if (!isConnected!) {
bluetooth.printCustom("thermal pinter", 0, 1);
for (int i = 0; i < 2; i++) {
bluetooth.printCustom("Welcome", 0, 1);
bluetooth.printNewLine();
}
}
});
}
}
Hello and welcome on SO!
I don't know much about bluetooth printing or if the methods you're using exists and are used correctly, but at least I can notice that your code is sending the order to print when the printer is NOT connected.
See here:
if (!isConnected!) {
//the code below is executed only if isConnected is false, but seems like you want it to be the opposite
bluetooth.printCustom("thermal pinter", 0, 1);
for (int i = 0; i < 2; i++) {
bluetooth.printCustom("Welcome", 0, 1);
bluetooth.printNewLine();
}
}
Taking for granted that the code is correct, the line if (!isConnected!) will perform the code in the {} that follows only when the printer is not connected. Try removing the ! before isConnected and see if it works. Again, this is simply a wild guess judging on your variables name and such, I can't really say that the problem lies there.
In my project I'm using a button that enables and disables spatial mapping/awareness. It works quite good, in 7 times out of 10. The following behaviour can be observed in the other 3 times. By disabling the spatial-map-mesh (polygones), they disappear to 90%. But 10% stays where it is. Repeated pressing of my button (dis/enable spatial mapping) does not help, the 10% just stays. Any suggestions what the reason for that behaivour could be?
Code Observer:
public void ToggleObservers()
{
if (SpatialAwarenessSystem == null) return;
// If running → stop "running"
if (_isObserverRunning)
{
SetVisualizationOfSpatialMapping(SpatialAwarenessMeshDisplayOptions.None);
SpatialAwarenessSystem.SuspendObservers();
_isObserverRunning = false;
// Disabling the whole system boosts performance ~+5fps
if (ShouldSpatialSystemBeDisabled)
SpatialAwarenessSystem.Disable();
}// Else start spatial mapping
else
{
SpatialAwarenessSystem.Enable();
SetVisualizationOfSpatialMapping(SpatialAwarenessMeshDisplayOptions.Visible);
SpatialAwarenessSystem.ResumeObservers();
_isObserverRunning = true;
}
}
Code Set Visualtization of Spatial Mapping:
public void SetVisualizationOfSpatialMapping(SpatialAwarenessMeshDisplayOptions option)
{
if (CoreServices.SpatialAwarenessSystem is IMixedRealityDataProviderAccess provider)
{
foreach (var observer in provider.GetDataProviders())
{
if (observer is IMixedRealitySpatialAwarenessMeshObserver meshObs)
{
meshObs.DisplayOption = option;
}
}
}
}
Edit:
Bug Report on Github.
I also hit this issue. Until this is fixed in MRTK, you can patch this.
Edit this file:
MixedRealityToolkit.Providers\WindowsMixedReality\WindowsMixedRealitySpatialMeshObserver.cs
Find the suspend function, and add the code between // Begin Patch and // End Patch:
public override void Suspend()
{
#if UNITY_WSA
if (!IsRunning)
{
Debug.LogWarning("The Windows Mixed Reality spatial observer is currently stopped.");
return;
}
// UpdateObserver keys off of this value to stop observing.
IsRunning = false;
// Clear any pending work.
meshWorkQueue.Clear();
// Begin Patch
if (outstandingMeshObject != null)
{
ReclaimMeshObject(outstandingMeshObject);
outstandingMeshObject = null;
}
// End Patch
#endif // UNITY_WSA
}
This appears to be a race condition where the mesh detected logic does not honor the state of the observer (suspended or resumed). Thanks for the issue #Perazim!
so i am trying to detect if i click on a object with tag "solarsystem" and if so, then load that solarsystem onto the other scene. this code worked perfectly fine before, but now it crashes in such a way that i have to end unity from the task manager with the end task button to even close it. it just stops responding completely.
here is the code where i believe to have found the error after messing around with many Debug.log s to find where the code stopped and therefore find out where unity stops responding:
RaycastHit[] hit = Physics.RaycastAll(cursorPosition, Vector3.forward,15f);
Debug.Log("test2");//this is printed to the console - code crashes below this line
for(int i = 0; i < hit.Length; i++)
{
Debug.Log("hit"); // this is never printed to console - code crashes above this line
if(currentScene == "Universe")
{
if(hit[i].collider.gameObject.tag == "SolarSystem")
{
ChangeScene("SolarSystem");
SolarSystem clickedSolarSystem = hit[i].collider.gameObject.GetComponent<SystemObjectLink>().LinkedClass;
SolarSystem LoadedSolarSystem = SolarSystemCamera.GetComponent<SolarSystem>() as SolarSystem;
LoadedSolarSystem = clickedSolarSystem;
Debug.Log("generating system clicked on");
if (LoadedSolarSystem.preGenerated == false)
{
LoadedSolarSystem.Generate();
}
else
{
LoadedSolarSystem.Regenerate();
}
break;
}
}
if(currentScene == "SolarSystem")
{
if (hit[i].collider != null)
{
if (hit[i].collider.gameObject.tag == "Planet")
{
Target = hit[i].collider.gameObject;
break;
}
else if (hit[i].collider.gameObject.tag == "Moon")
{
Target = hit[i].collider.gameObject;
break;
}
Target = hit[i].collider.gameObject;
}
}
}
i had an for(;;) statement with a hardcoded
if(<state>){
break:
}
statement to break the infinite loop. but as i click on an object in the game. it checks the code for any errors before running it. when it does this it gets caught in the infinite loop and so to fix it i did this
for(;errorIndex<99; errorIndex++){
}
my mistake and what i learned:
never use a while(true) loop or a for loop without a way of getting out of itself (for(;;))
if the unity engine/editor ever stops responding it is because it is cought in an infinite loop- look over your code and ensure there is no possible way any of your loops can go on forever
I am trying to redirect output so I can send it over the network. For some reason if you run the code while debugger attached it works perfectly. Once you start the application in normal way the code freezes on the read function and never returns. If someone has any pointers I will highly appreciate it.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void) {
static int pipePair[2];
if ( pipe(pipePair) != 0) {
return;
}
dup2(pipePair[1],STDOUT_FILENO);
while (true) {
char * buffer = calloc(sizeof(char), 1024);
ssize_t readCount = read(pipePair[0],buffer,1023);
if (readCount > 0) {
buffer[readCount] = 0;
NSString * log = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
//sent it over network
}
if (readCount == -1) {
return;
}
}
});
Apparently in iOS 5.1 writing to stdout was disallowed. http://spouliot.wordpress.com/2012/03/13/ios-5-1-vs-stdout/
I have a PNG in a UIImageView with alpha around the edges (let's say a circle). When I tap it, I want it to register as a tap for the circle if I'm touching the opaque bit, but a tap for the view behind if I touch the transparent bit.
(BTW: On another forum, someone said PNGs automatically do this, and a transparent PNG should pass the click on to the view below, but I've tested it and it doesn't, at least not in my case.)
Is there a flag I just haven't flipped, or do I need to create some kind of formula: "if tapped { get location; calculate distance from centre; if < r { touched circle } else { pass it on } }"?
-k.
I don't believe that PNGs automatically do this, but can't find any references that definitively say one way or the other.
Your radius calculation is probably simpler, but you could also manually check the alpha value of the touched pixel in your image to determine whether to count it as a hit. This code is targetted at OS X 10.5+, but with some minor modifications it should run on iPhone: Getting the pixel data from a CGImage object. Here is some related discussion on retrieving data from a UIImage: Getting data from an UIImage.
I figured it out...the PNG, bounding box transparency issue and being able to click through to another image behind:
var hitTestPoint1:Boolean = false;
var myHitTest1:Boolean = false;
var objects:Array;
clip.addEventListener(MouseEvent.MOUSE_DOWN, doHitTest);
clip.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
clip.buttonMode = true;
clip.mouseEnabled = true;
clip.mouseChildren = true;
clip2.addEventListener(MouseEvent.MOUSE_DOWN, doHitTest);
clip2.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
clip2.buttonMode = true;
clip2.mouseEnabled = true;
clip2.mouseChildren = true;
clip.rotation = 60;
function doHitTest(event:MouseEvent):void
{
objects = stage.getObjectsUnderPoint(new Point(event.stageX, event.stageY));
trace("Which one: " + event.target.name);
trace("What's under point: " + objects);
for(var i:int=0; i
function stopDragging(event:MouseEvent):void
{
event.target.stopDrag();
}
function realHitTest(object:DisplayObject, point:Point):Boolean
{
/* If we're already dealing with a BitmapData object then we just use the hitTest
* method of that BitmapData.
*/
if(object is BitmapData)
{
return (object as BitmapData).hitTest(new Point(0,0), 0, object.globalToLocal(point));
}
else {
/* First we check if the hitTestPoint method returns false. If it does, that
* means that we definitely do not have a hit, so we return false. But if this
* returns true, we still don't know 100% that we have a hit because it might
* be a transparent part of the image.
*/
if(!object.hitTestPoint(point.x, point.y, true))
{
return false;
}
else {
/* So now we make a new BitmapData object and draw the pixels of our object
* in there. Then we use the hitTest method of that BitmapData object to
* really find out of we have a hit or not.
*/
var bmapData:BitmapData = new BitmapData(object.width, object.height, true, 0x00000000);
bmapData.draw(object, new Matrix());
var returnVal:Boolean = bmapData.hitTest(new Point(0,0), 0, object.globalToLocal(point));
bmapData.dispose();
return returnVal;
}
}
}