FallFury är ett 2D spel skrivet i C++, DirectX och XAML för Windows 8. Källkoden och en djup beskrivning av hur spelet gjordes finns också. Detta kan vara ett jätteroligt sätt att lära sig Windows 8 och spelprogrammering på samma gång.
« januari 2013 | Main | mars 2013 »
FallFury är ett 2D spel skrivet i C++, DirectX och XAML för Windows 8. Källkoden och en djup beskrivning av hur spelet gjordes finns också. Detta kan vara ett jätteroligt sätt att lära sig Windows 8 och spelprogrammering på samma gång.
Posted at 15.34 in Windows 8 | Permalink | Comments (0) | TrackBack (0)
Ojoj. Det finns många open source projekt. Jag har svårt att hänga med . Men ibland sticker något projekt ut extra mycket, speciellt om man läser en person som är exalterad över det. Ett sådan ramverk är Nancy och personen är Marcus Hammarberg.
Var med och lyssna på vad Nancy är och vad det skall användas till. Jag kan inte heller låta bli att fråga Marcus mer generellt om Open Source och hur han hittar alla dessa ramverk och hur man väljer ut ett bra.
http://NancyFx.org
http://github.com/NancyFx
http://github.com/NancyFx/Nancy
http://bit.ly/NancyTesting
http://blog.markrendle.net/
http://bit.ly/NancyTesting
Andreas Håkansson heter skaparen av Nancy (http://thecodejunkie.com
Han har gjort det tillsammans med Steven Robbins (http://www.grumpydev.com/
Hjälp kring Nancy får man bäst på https://jabbr.net/#/rooms/nancyfx eller på https://groups.google.com/forum/?fromgroups#!forum/nancy-web-framework
Posted at 09.25 in devcast | Permalink | Comments (0) | TrackBack (0)
Skapa tre bra appar för Windows 8 och en för Windows Phone och till slut en valfri för Windows 8 eller Windows Phone så är du med i tävlingen. I vinstpotten ligger 50 Acer Iconia W510.
Har du fastnad och behöver hjälp med dina Windows 8 appar så finns det hjälp att få. Jessica Engström, (ja, det är en riktig person som bor i Sverige, ingen Bot eller marknadsföringstrick), som ni kan kontakta. Alla hennes kontaktuppgifter finner ni här.
Vår svenska huvudsida för apputveckling heter Dev.Destination. Här kan ni också finna min podcast Dev.Cast.
Posted at 09.24 | Permalink | Comments (0) | TrackBack (0)
Detta är del av en artikelserie Guppy - Hur bygger man en riktig tjänst med Azure Mobile Services?
Azure Mobile Services stödjer de vanligasta datatyperna såsom string, bool, DateTime och numeriska datatyper, vilka är de som man oftast använder. Men om man exempelvis vill spara en TimeSpan eller någon annan spännande datatyp måste man hjälpa till med konverteringen mellan typen och JSon, vilket är själva transportprotokollet mellan klienten och tjänsten.
Detta inlägg tar mycket inspiration ifrån Supporting arbitrary types in Azure Mobile Services managed client.
Säg att vi har en klass som vi vill spara i Azure Mobile Services som ser ut så här:
[DataTable(Name ="session")] public class Session { [DataMember(Name="id")] public int Id; [DataMember(Name="name")] public string Name; [DataMember(Name = "length")] public TimeSpan Length; }
Om vi sedan gör ett anrop för att spara en nytt objekt i tjänsten:
var aSession = new Session() { Name = "Go with C#", Length = new TimeSpan(1,10,0) };
await App.MobileService.GetTable<Session>().InsertAsync(aSession);
Så får vi följande fel ifrån tjänsten:
Cannot serialize member 'length' of type 'System.TimeSpan' declared on type 'Session'.
För att lösa detta behöver vi implementera ett interface, vilket använts sedan av klienten för att konvertera mellan olika datatyper när datat skickas och tas emot.
Interfacet heter IDataMemberJsonConverter, vilket har två metoder ConvertFromJson och ConvertToJson.
OBSERVERA – Det är olika metodsignaturer för ConvertFromJson beroende på om klienten är Windows 8 eller Windows Phone 8.
En implementation för detta interface för TimeSpan och Windows 8 och Windows Phone 8
class TimeSpanJsonConverter : IDataMemberJsonConverter { private static readonly IJsonValue NullJson = JsonValue.Parse("null"); public object ConvertFromJson(Windows.Data.Json.IJsonValue value) { TimeSpan result = default(TimeSpan); if (value != null && value.ValueType == JsonValueType.String) { result = TimeSpan.Parse(value.GetString()); } return result; } public Windows.Data.Json.IJsonValue ConvertToJson(object instance) { if (instance is TimeSpan) { TimeSpan timeSpan = (TimeSpan)instance; return JsonValue.CreateStringValue(timeSpan.ToString()); } else { return NullJson; } } }
class TimeSpanJsonConverter : IDataMemberJsonConverter { public object ConvertFromJson(JToken value) { TimeSpan result = default(TimeSpan); if (value != null) { } return result; } public JToken ConvertToJson(object instance) { if (instance is TimeSpan) { TimeSpan timeSpan = (TimeSpan) instance; return JValue.CreateString(timeSpan.ToString()); } else { return default(JValue); } } }
Vi behöver lägga till attribut i klassen Session, DataMemberJsonConverter, som talar om att fältet Length skall konvertas när det skickas och tas emot.
public class Session { [DataMember(Name="id")] public int Id; [DataMember(Name="name")] public string Name; [DataMember(Name = "length"), DataMemberJsonConverter(ConverterType = typeof(TimeSpanJsonConverter))] public TimeSpan Length; }
Sedan funkar allt som vanligt, inklusive automatgenerering av fältet i tabellen, om det ej finns tidigare.
Posted at 09.07 in Azure, Guppy | Permalink | Comments (0) | TrackBack (0)
En av de begränsningar som idag finns i Azure Mobile Services är att allt är tabellorienterat. Man skapar tabeller på serversidan och för varje tabell finns det fyra fördefinierade metoder som man kan anropa ifrån klientsidan: insert, update, delete och read. Hur gör man om man istället vill anropa någonting som inte primärt har en relation till någon av de tabeller som finns?
Idag måste man tweaka detta, eftersom det beskrivna ovan gäller. Det jag har gjort är att skapa en tom tabell med namnet på den metod som jag vill anropa. I mitt exempel nedan heter tabellen CheckInWithNFC. Sedan använder jag mig av funktionen insert, för den ligger mest rätt i det som jag vill göra i metoden, för att starta den.
Så här ser klientsidan ut. Detta exemplet är för Windows 8.
var tableCheckInWithNfc = App.MobileService.GetTable("CheckInWithNFC");
var nfcId = 120;
var item = new JObject(); item.Add("nfcId", nfcId); await tableCheckInWithNfc.InsertAsync(item);
Det första jag gör är att få tag på objektet som beskriver tabellen, tableCheckInWithNfc, sedan bygger jag upp de inparametrar som jag vill skicka med. I detta fall är det endast en parameter, nfcId. Dessa läggs in i en Json-lista. Till slut anropar jag insert på serversidan och skickar med inparametervariabeln.
Serversidan ser ut så här. Jag har bara tagit med det som är väsentligt för att beskriva lösningen.
function insert(item, user, request) { var nfcId = item.nfcId; ... }
Som ni ser, är det enkelt. Genom item.nfcId kommer jag åt det som jag skickade ifrån klienten. Nu kan jag utföra det som jag behöver i metoden.
Posted at 13.30 in Azure, Guppy | Permalink | Comments (0) | TrackBack (0)
Många av oss som har jobbat med webbutveckling har vuxit upp med ASP och sedan ASP.NET. Men om man tänker efer är det en teknologi som verkligen har utvecklats sedan det lanserades som ASP+. Fredrik Normén (Squeed) och jag tänker tillbaka, diskuterar vad som gäller idag och vad som kanske kan hända imorgon.
Posted at 09.04 in devcast | Permalink | Comments (0) | TrackBack (0)
Detta är del av en artikelserie Guppy - Hur bygger man en riktig tjänst med Azure Mobile Services?
Ibland (ofta) räcker det inte med att gå emot en tabell i sin databas, vilket är standarden för Azure Mobile Services. När detta inte räcker kan man använda sig av T-SQL istället. I Guppy har jag exempelvis många joins för att hitta rätt information. Detta är inget som helst problem att göra detta.
Här är ett exempel:
var query = "select top 1 pfu.positionName, g.groupName from groupy.PositionForUser pfu " + "join groupy.PositionRegistredForGroups prfg on pfu.id = prfg.positionId " + "join groupy.[Group] g on prfg.groupId = g.id " + "where pfu.userId = ? " + "order by pfu.checkInTime desc"mssql.query(query, [userId], {success: function(results){
request.respond(statusCodes.OK, results);
}});
Först skapar jag själva satsen som skall utföras i T-SQL. Observera att jag använder mig av ett ? som platshållare för de parametrar som jag sedan skall infoga.
Sedan använder jag mig av objektet mssql för att göra själva frågan och precis som med andra objekt så använts ett asynkront mönster, vilket innbär att jag bland annat anger vilken metod som skall köras när frågans svar returneras. Det är detta som defineras i den tredje parametern till mssql.query().
Observera att mssql skiljer sig lite ifrån samma objekt i Node.sj. Man behöver inte ange någon connection string och man kan ange separata call-backs för success och error.
Posted at 12.44 in Azure, Guppy | Permalink | Comments (0) | TrackBack (0)
modern.IE är en ny webbplats där Microsoft har samlat flera resurser som hjälper dig som utvecklar och testar webbplatser att stödja Internet Explorer.
För mig är det främst två saker i denna verktygslåda som sticker ut.
Med detta verktyg kan man snabbt skanna av en sida och se om det finns saker på den som inte är up-to-date, inte endast för IE utan för alla moderna webbläsare. Det tar tio sekunder, testa själv här. http://www.modern.ie/report
De som sitter och utvecklar på andra operativsystem än Windows kan ibland har det riktigt jobbigt att köra sin webbsidor i Internet Explorer. På modern.IE finns det två olika lösningar för detta:
Posted at 10.12 in IE | Permalink | Comments (0) | TrackBack (0)
Vad händer med mjukvaruarkitekturen när nya förutsättningar och trender dyker upp? Vad har hänt med SOA (Service Oriented Architecture) och andra frågor diskuterar jag med Sten Sundblad, en av nestorerna inom mjukvaruarkitektur i Sverige.
Posted at 10.27 in Arkitektur, devcast | Permalink | Comments (0) | TrackBack (0)
Detta är del av en artikelserie Guppy - Hur bygger man en riktig tjänst med Azure Mobile Services?
I Guppy har jag en tabell för användarna, User. I denna tabell finns ett fält som heter DisplayName. Där lagrar jag ett namn som användaren vill skall vara dess synliga namn i tjänsten. På klientsidan vill jag inte först kolla om en användare finns för att sedan använda metoden insert för att skapa en ny användare eller update för att uppdatera en befintlig. Jag vill istället alltid anropa insert och sedan får serversidan ta hand om detta.
Klientsidan ser inte något speciell ut:
public static async Task UpdateUserInformationAsync(IMobileServiceTable<User> userTable, User user) { var u = new User() { displayName = user.displayName }; await userTable.InsertAsync(u); }
userTable är egentligen följande App.MobileService.GetTable<User>(), som helt enkelt pekar ut tabellen User på serversidan. Det är på denna klass som jag använder mig av InsertAsync för att göra anropet. User är min klass som avspeglar tabellen User.
Det är på serversidan som logiken sker:
function insert(item, user, request) { item.userExternalAuthenticationId = user.userId; var userTable = tables.getTable('user'); userTable.where({ userExternalAuthenticationId: item.userExternalAuthenticationId }).read({ success: function(results) { if (results.length > 0) { var row = results[0]; row.displayName = item.displayName; userTable.update(row); request.respond(statusCodes.OK); } else { request.execute(); } }}); }
Det första jag gör är att jag sparar den externa användaridentiteten i userExternalAuthenticationId. I Guppy är detta användarens twitteridentitet.
Jag får tag på tabellen User genom metoden tables.getTable(“user”). Den använder jag sedan för att med metoden where söka i tabellen efter det userExternalAuthenticationId för att se om användaren redan finns lagrad där.
Syntaxen för where ser kanske lite konstig ut. Detta är ett asynkront mönster som används på serversidan. Genom att man anropar where på detta sätt så kan man fortsätta att göra andra saker i sitt skript tills sökningen är klar. När sökningen är klar kommer funktionen som är definierad av success att köras.
Denna funktion kollar om results innehåller några rader. Om den gör detta då vet vi att användaren redan finns i tabellen och vi gör istället update på tabellen där vi har bytt ut displayName mot det nya som användaren har givit. Om ingen rad har hittats då fortsätter vi och gör en vanlig insert.
Observera att vi alltid skall avsluta en metod med att antingen köra request.execute() eller request.response(). I response kan man ange vilken statusCode som skall skickas tillbaka.
Posted at 10.21 | Permalink | Comments (0) | TrackBack (0)
Recent Comments